Status: Proven Category: Grammar Application First Documented: January 20, 2026 Ratified: January 20, 2026 (Grammar Implementation)
Features generate rich contextual data (GitHub activity, calendar events, task status), but presenting this raw data to users feels mechanical and database-like. Common challenges:
This creates features that feel like tools rather than collaborative experiences with Piper as a present, helpful entity.
Implement a Personality Bridge that transforms raw data into warm, conversational narrative:
A Personality Bridge is a transformation layer that converts feature output (data) into user-facing narrative (experience). The pattern emphasizes:
adapt_for_[place](), apply_personality()from typing import Dict, Any
from services.personality.personality_profile import PersonalityProfile
class [Feature]ToChatBridge:
"""
Transform [feature] data into conversational format.
Separates business logic from presentation personality.
"""
def adapt_for_chat(self, raw_data: Dict[str, Any]) -> str:
"""
Convert raw feature data to conversational format.
Args:
raw_data: Feature Result dataclass as dict
Returns:
Conversational narrative suitable for chat interface
"""
# Convert structure to prose
sections = []
if raw_data.get("findings"):
sections.append(self._format_findings(raw_data["findings"]))
if raw_data.get("suggestions"):
sections.append(self._format_suggestions(raw_data["suggestions"]))
return "\n\n".join(sections)
def apply_personality(
self,
content: str,
profile: PersonalityProfile,
context: Dict[str, Any]
) -> str:
"""
Apply personality preferences to content.
Args:
content: Base conversational content
profile: User's personality preferences
context: Additional context (accomplishment level, urgency, etc.)
Returns:
Content enhanced with personality dimensions
"""
# Add warmth based on context (see Pattern-053: Warmth Calibration)
enhanced = self._enhance_with_warmth(content, context)
# Add action orientation if appropriate
if context.get("suggest_actions"):
enhanced = self._add_action_suggestions(enhanced, context)
# Add presence language ("I noticed", "I found")
enhanced = self._add_presence(enhanced)
return enhanced
def _format_findings(self, findings: List[str]) -> str:
"""Format findings with Piper's voice."""
if not findings:
return ""
# Add presence and warmth
intro = "Here's what I found:"
items = [f"• {finding}" for finding in findings]
return f"{intro}\n" + "\n".join(items)
def _add_presence(self, content: str) -> str:
"""Add Piper's presence to content."""
# Transform passive voice to active Piper voice
# "5 items were found" → "I found 5 items"
# "Activity was detected" → "I noticed activity"
return content # Implementation details
File: services/personality/standup_bridge.py:70-86
class StandupToChatBridge:
"""Transform standup data to conversational format with personality."""
def apply_personality_to_standup(
self, standup_data: Dict[str, Any], profile: PersonalityProfile
) -> str:
"""Apply personality preferences to standup content"""
# First convert to chat format (structure → prose)
base_content = self.adapt_standup_for_chat(standup_data)
# Then apply personality enhancements (add warmth, presence, action)
enhanced_content = self._enhance_with_personality(base_content, profile, standup_data)
return enhanced_content
File: services/personality/standup_bridge.py:88-114
def adapt_standup_for_chat(self, standup_data: Dict[str, Any]) -> str:
"""Convert standup data structure to conversational format."""
sections = []
# Yesterday accomplishments - add presence and warmth
if standup_data.get("yesterday_accomplishments"):
accomplishments = standup_data["yesterday_accomplishments"]
intro = self._get_accomplishment_intro(len(accomplishments)) # Warmth calibration
sections.append(f"{intro}\n" + "\n".join(f"• {item}" for item in accomplishments))
# Today priorities - action orientation
if standup_data.get("today_priorities"):
priorities = standup_data["today_priorities"]
sections.append("Today's focus:\n" + "\n".join(f"• {item}" for item in priorities))
# Blockers - empathy and problem-solving tone
if standup_data.get("blockers"):
blockers = standup_data["blockers"]
# Note: "Current challenges to work through" not "Blockers"
sections.append("Current challenges to work through:\n" + "\n".join(f"• {item}" for item in blockers))
return "\n\n".join(sections)
Personality application (services/personality/standup_bridge.py:116-155):
def _enhance_with_personality(
self, base_content: str, profile: PersonalityProfile, standup_data: Dict[str, Any]
) -> str:
"""Enhance content with personality dimensions."""
# Warmth calibration based on accomplishment level
accomplishment_level = self._calculate_accomplishment_level(standup_data)
warmth_prefix = self._get_accomplishment_prefix(accomplishment_level)
# Action orientation - suggest next steps
suggestions = []
if standup_data.get("github_activity"):
suggestions.append("Consider reviewing recent PRs")
# Presence language - "I noticed", "I see", "I found"
# ... transform passive to active voice
return f"{warmth_prefix}\n\n{base_content}\n\n{self._format_suggestions(suggestions)}"
Evidence of transformation:
Before (raw data):
{
"yesterday_accomplishments": ["Fixed bug #123", "Reviewed PR #456"],
"blockers": ["Waiting on API key"]
}
After (personality bridge):
Great progress yesterday! 🎉
• Fixed bug #123
• Reviewed PR #456
Current challenges to work through:
• Waiting on API key
Consider reaching out to the team about that API access.
services/personality/personality_profile.py✅ Use Personality Bridge when:
❌ Don’t use when:
services/personality/standup_bridge.py - StandupToChatBridge (reference implementation)High Priority (should adopt pattern):
Medium Priority:
[Feature]ToChatBridge classadapt_for_chat() method (structure → prose)apply_personality() method (add warmth/presence/action)_format_[section]() methods for each data typeProven Pattern - Successfully implemented in:
services/personality/standup_bridge.pyP0 Analysis Evidence:
Grammar Audit Evidence:
Pattern Identified: January 19, 2026 (P0 Morning Standup Analysis) Ratified: January 20, 2026 Category: Grammar Application