Code Speaks, Feelings Whisper: Reading Team Mood on Your Radar

The Problem. 

Commit and cycle-time charts show what happened; they rarely reveal how the team feels. Stress signals appear first in Slack emojis, tense pull-request comments, or an awkward silence during stand-ups. When those signals go unnoticed, burnout sneaks in, creativity plummets, and velocity quickly drops. 

The Agility. 

At the core of business agility is respect for the entire system, both code and people. A Sentiment Overlay embodies that principle by combining conversational data with commit clusters. 

Drawing from Lyssa Adkins’ coaching advice on “emotional intelligence” and HBR’s Happiness Dividend research, we consider mood as an early-warning indicator that you can visualize, measure, and respond to just as swiftly as fixing a failing test. 

The Scrum. 

- Add Sentiment in One Sprint

StepActionCommand / Snippet
1Create a Slack bot token with channels:history scope.export SLACK_BOT_TOKEN=xoxb-…
2Pull last 7 days of messages from #dev & #standup.python ingest_slack.py --channels dev,standup --days 7 --out data/slack.json
3Run sentiment scoring (OpenAI or open-source model).python slack_sentiment.py data/slack.json data/sentiment.csv
4Expose new API route in radar.py.@app.route("/api/sentiment") … return sentiment by day
5Patch radar.js to draw a mood ring per sprint (green ↔ red opacity).See GitHub branchsentiment-day for full diff.
6Review overlay in retro; pick one “empathy action” for the lowest-mood cluster.10-min screen-share + coaching cue card.
Key Python snippet (slack_sentiment.py)
import os, json, csv, openai, textblob
openai.api_key = os.getenv("OPENAI_API_KEY")

def score(msg):
    # fallback to TextBlob if no OpenAI key
    if openai.api_key:
        rsp = openai.ChatCompletion.create(
            model="gpt-4o",
            messages=[{"role":"user","content":f"Sentiment 0-1 for: {msg}"}]
        )
        return float(rsp.choices[0].message.content.strip())
    return textblob.TextBlob(msg).sentiment.polarity

rows=[]
for m in json.load(open("data/slack.json")):
    rows.append({"ts":m["ts"], "user":m["user"], "score":score(m["text"])})
csv.DictWriter(open("data/sentiment.csv","w"), rows[0].keys()).writerows(rows)

The Outcome. 

The radar now glows with mood around each theme: a red halo over Payments warns of increasing stress, while a green ring on UI highlights growing excitement. Teams move quickly beyond guesswork: they reassign reviewers to the Payments group, celebrate UI successes publicly, and coach individuals before burnout occurs. 

A full-scale sample showing code commits (colored by risk) plus translucent sentiment halos; green for high morale, amber for neutral, red for stressed, exactly what the Sentiment Overlay step will deliver once your Slack and PR data flow in (ours is just sample data). 

Let’s Do This! 

Code tells one side of the story, emotion reveals the rest. By overlaying Slack and PR sentiment on your commit clusters, you unlock targeted, humane coaching cues in real time. 

Tomorrow we’ll add cycle-time and WIP bars, unifying flow with code and mood so you can see what’s stuck and who’s stuck at a glance.