# Daily Standup Report Workflow

**Project**: {{ project.name }}
**Workflow**: Daily Standup Report
**Purpose**: Generate automated daily standup reports for the active sprint

## Output Formatting Requirements

**IMPORTANT**: When generating reports, use actual Unicode emojis, NOT GitHub-style shortcodes:
- ✅ Correct: `⚠️ Warning` or `ℹ️ Info`
- ❌ Incorrect: `:warning:` or `:information_source:`

Status indicators to use:
- ✅ Completed / On track
- ⚠️ Warning / Below target
- ❌ Critical / Blocked
- ℹ️ Information
- 🔴 High priority
- 🟡 Medium priority
- 🟢 Low priority / Good

## Overview

This lightweight workflow generates daily standup reports showing what was completed yesterday, what's planned for today, and any blockers. Perfect for distributed teams or async standups.

## Prerequisites

- Active sprint in {{ work_tracking.platform }}
- Work items with recent activity

## Initialize Work Tracking

```python
# Initialize work tracking adapter (auto-selects Azure DevOps or file-based)
import sys
sys.path.insert(0, ".claude/skills")
from work_tracking import get_adapter
from workflows.utilities import (
    analyze_sprint,
    verify_work_item_states,
    get_recent_activity,
    identify_blockers
)
from datetime import datetime, timedelta

adapter = get_adapter()
print(f"📋 Work Tracking: {adapter.platform}")

# Get current sprint name (replace CURRENT_SPRINT with actual sprint)
current_sprint = "Sprint 1"  # Update this
```

## Workflow Steps

### Step 1: Gather Yesterday's Activity

1. **Query completed work (last 24 hours):**
   ```python
   # Use workflow utility to get recent activity
   activity_result = get_recent_activity(adapter, current_sprint, hours=24)

   recent_items = activity_result['recent_items']
   print(f"Found {activity_result['recent_count']} items updated since yesterday")
   print(f"Total items in sprint: {activity_result['total_items']}")

   for item in recent_items:
       print(f"  WI-{item['id']}: {item['title']} [{item['state']}]")

   # Check for errors
   if activity_result['errors']:
       print(f"⚠️ Errors during activity query:")
       for error in activity_result['errors']:
           print(f"  - {error}")
   ```

2. **Categorize changes:**
   - ✅ Completed: Items moved to "Done"/"Closed"
   - ⚙️ In Progress: Items actively worked on
   - 🆕 Started: Items moved from "New" to "Active"
   - 🚫 Blocked: Items marked as blocked
   - 💬 Discussed: Items with new comments

### Step 1.5: Verify Work Item States Against External Source of Truth

**CRITICAL**: This step implements the "External Source of Truth" pattern from VISION.md. AI agents often claim work is complete when it isn't. This verification step catches divergence immediately.

1. **Use workflow utility to verify states against adapter:**
   ```python
   # Use workflow utility for external source of truth verification
   print("\n🔍 Verifying work item states against external source of truth...")

   verification_result = verify_work_item_states(adapter, recent_items)

   print(f"Verified {verification_result['verified_count']} work items")
   ```

2. **Display divergence warnings (informational only - workflow continues):**
   ```python
   # Display divergence summary
   if verification_result['divergence_count'] > 0:
       print(f"\n⚠️ DIVERGENCE DETECTED: {verification_result['divergence_count']} work item(s) need attention")
       print("=" * 80)

       for div in verification_result['divergences']:
           if div['severity'] == 'ERROR':
               print(f"  ❌ {div['id']}: {div['title']}")
               print(f"     {div['message']}")
           else:
               print(f"  ⚠️ {div['id']}: {div['title']}")
               print(f"     CLAIMED: {div['claimed_state']} | ACTUAL: {div['actual_state']}")

       print(f"\n📊 Divergence Summary:")
       print(f"   - {verification_result['summary']['errors']} ERROR(s)")
       print(f"   - {verification_result['summary']['warnings']} WARNING(s)")
       print(f"   - Action: Review work items and sync states in {adapter.platform}")
       print("=" * 80)
   else:
       print("✅ No divergence detected - all work item states match external source of truth")

   # Check for verification errors
   if verification_result['errors']:
       print(f"\n⚠️ Verification errors occurred:")
       for error in verification_result['errors']:
           print(f"  - {error}")

   # Store divergences for inclusion in report (Step 5)
   divergence_summary = {
       'count': verification_result['divergence_count'],
       'errors': verification_result['divergences'],
       'warnings': [d for d in verification_result['divergences'] if d['severity'] == 'WARNING']
   }
   ```

### Step 2: Identify Today's Focus

1. **Query active work items:**
   ```python
   # Get active work items for current sprint
   active_states = ['Active', 'In Progress', 'Doing']
   active_items = [
       item for item in adapter.query_sprint_work_items(current_sprint)
       if item.get('state') in active_states
   ]

   print(f"\n📋 Active Work Items ({len(active_items)}):")
   for item in active_items:
       points = item.get('story_points', item.get('fields', {}).get('Microsoft.VSTS.Scheduling.StoryPoints', '-'))
       assignee = item.get('assigned_to', 'Unassigned')
       print(f"  WI-{item['id']}: {item['title']}")
       print(f"    State: {item['state']} | Points: {points} | Assigned: {assignee}")
   ```

2. **Group by team member:**
   - List active items per person
   - Identify items without updates
   - Flag items at risk

### Step 3: Detect Blockers

1. **Use workflow utility to identify blockers:**
   ```python
   # Use workflow utility to identify blockers
   blocker_result = identify_blockers(adapter, current_sprint, stale_threshold_days=3)

   print(f"\n🚫 Blocker Analysis:")
   print(f"Total blockers detected: {blocker_result['total_blockers']}")
   print(f"Blocked state: {len(blocker_result['blocked_items'])}")
   print(f"Tagged as blocker: {len(blocker_result['tagged_items'])}")
   print(f"Stale (no updates 3+ days): {len(blocker_result['stale_items'])}")

   # Display impact
   print(f"\n📊 Impact:")
   print(f"Affected people: {blocker_result['impact']['affected_people']}")
   print(f"Story points at risk: {blocker_result['impact']['story_points_at_risk']}")

   # Display blocker details
   if blocker_result['blocked_items']:
       print(f"\n🔴 Blocked Items:")
       for item in blocker_result['blocked_items']:
           print(f"  - {item['id']}: {item['title']} ({item['story_points']} pts)")

   if blocker_result['stale_items']:
       print(f"\n⏰ Stale Items (no updates in 3+ days):")
       for item in blocker_result['stale_items']:
           print(f"  - {item['id']}: {item['title']} ({item['days_stale']} days stale)")

   # Check for errors
   if blocker_result['errors']:
       print(f"\n⚠️ Errors during blocker detection:")
       for error in blocker_result['errors']:
           print(f"  - {error}")
   ```

2. **Blocker detection includes:**
   - Items with "Blocked" state
   - Items tagged with "blocker"
   - Items with no updates in 3+ days
   - Impact analysis (affected people, story points at risk)

### Step 4: Analyze Sprint Progress

1. **Use workflow utility to analyze sprint:**
   ```python
   # Use workflow utility for comprehensive sprint analysis
   sprint_stats = analyze_sprint(adapter, current_sprint)

   print(f"\n📊 Sprint Progress:")
   print(f"Total items: {sprint_stats['total_items']}")
   print(f"Completion rate: {sprint_stats['completion_rate']:.1f}%")
   print(f"Velocity (completed points): {sprint_stats['velocity']}")

   print(f"\nBy State:")
   for state, count in sprint_stats['by_state'].items():
       print(f"  {state}: {count}")

   print(f"\nStory Points:")
   print(f"  Total: {sprint_stats['story_points']['total']}")
   print(f"  Completed: {sprint_stats['story_points']['completed']}")
   print(f"  In Progress: {sprint_stats['story_points']['in_progress']}")
   print(f"  Not Started: {sprint_stats['story_points']['not_started']}")

   # Check for errors
   if sprint_stats['errors']:
       print(f"\n⚠️ Errors during sprint analysis:")
       for error in sprint_stats['errors']:
           print(f"  - {error}")
   ```

{% if config.is_agent_enabled('scrum-master') %}
### Step 5: Generate Standup Report

1. **Read agent definition:** `.claude/agents/scrum-master.md`
2. **Task:** "Generate a concise daily standup report:
   - Summarize yesterday's accomplishments (from activity_result)
   - List today's planned work by team member (from active_items)
   - Highlight blockers requiring attention (from blocker_result)
   - Include work item state verification results (from divergence_summary)
   - Note sprint progress toward goal (from sprint_stats)
   - Keep it brief and action-oriented"
3. **Spawn agent** using Task tool with model `{{ config.get_agent_model('scrum-master') or 'haiku' }}`
4. **Input:** activity_result, active_items, blocker_result, divergence_summary, sprint_stats
5. **Display output** to user

{% endif %}
### Step 6: Format and Distribute Report

Generate report in markdown format (template shown below with placeholder data that would be filled at runtime).

**IMPORTANT**: Include divergence summary section if any divergences were detected:

```python
# Generate report with divergence section
report = f"""
# Daily Standup Report
**Date**: {datetime.now().strftime('%Y-%m-%d')}
**Sprint**: {current_sprint}

## Yesterday's Accomplishments
- Found {activity_result['recent_count']} items updated in last 24 hours
[List completed work items from activity_result['recent_items']]

## Work Item State Verification
"""

# Add divergence section
if divergence_summary['count'] > 0:
    report += f"⚠️ **DIVERGENCE DETECTED**: {divergence_summary['count']} work item(s) need attention\n\n"

    error_count = len([d for d in divergence_summary['errors'] if d['severity'] == 'ERROR'])
    warning_count = len(divergence_summary['warnings'])

    if error_count > 0:
        report += f"### Errors ({error_count})\n"
        for error in divergence_summary['errors']:
            if error['severity'] == 'ERROR':
                report += f"- ❌ **{error['id']}**: {error['title']}\n"
                report += f"  - {error['message']}\n"
        report += "\n"

    if warning_count > 0:
        report += f"### Warnings ({warning_count})\n"
        for warning in divergence_summary['warnings']:
            report += f"- ⚠️ **{warning['id']}**: {warning['title']}\n"
            report += f"  - Claimed: {warning['claimed_state']} | Actual: {warning['actual_state']}\n"
        report += "\n"

    report += f"**Action Required**: Review and sync work item states in {adapter.platform}\n\n"
else:
    report += "✅ **All work item states verified** - no divergence detected\n\n"

report += f"""
## Today's Focus
[List planned work items from active_items]

## Blockers
- Total blockers: {blocker_result['total_blockers']}
- Affected people: {blocker_result['impact']['affected_people']}
- Story points at risk: {blocker_result['impact']['story_points_at_risk']}

## Sprint Progress
- Total items: {sprint_stats['total_items']}
- Completion rate: {sprint_stats['completion_rate']:.1f}%
- Velocity: {sprint_stats['velocity']} story points completed
"""
```

### Step 7: Distribute Report

1. **Save to file:**
   ```bash
   # Save to reports directory
   mkdir -p .claude/reports/daily
   echo "$report" > .claude/reports/daily/$(date +%Y-%m-%d)-standup.md
   ```

2. **Post to team channels** (configure webhook URLs in environment)

3. **Email to stakeholders** (optional)

## Automation Setup

### Run Automatically Every Morning

**GitHub Actions** (`.github/workflows/daily-standup.yml`):
{% raw %}
```yaml
name: Daily Standup Report

on:
  schedule:
    - cron: '0 9 * * 1-5'  # Weekdays at 9 AM
  workflow_dispatch:  # Manual trigger

jobs:
  standup-report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.10'

      - name: Install framework
        run: pip install trustable-ai

      - name: Generate standup report
        env:
          AZURE_DEVOPS_PAT: ${{ secrets.AZURE_DEVOPS_PAT }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        run: |
          cwf workflow run daily-standup

      - name: Commit report
        run: |
          git config user.name "Daily Standup Bot"
          git config user.email "bot@yourcompany.com"
          git add .claude/reports/daily/
          git commit -m "Daily standup report $(date +%Y-%m-%d)" || true
          git push
```
{% endraw %}

**Azure DevOps Pipeline** (`azure-daily-standup.yml`):
{% raw %}
```yaml
schedules:
  - cron: "0 9 * * 1-5"
    displayName: Daily Standup Report
    branches:
      include:
        - main
    always: true

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: '3.10'

  - script: |
      pip install trustable-ai
      cwf workflow run daily-standup
    displayName: 'Generate Daily Standup'
    env:
      AZURE_DEVOPS_PAT: $(AZURE_DEVOPS_PAT)
      TEAMS_WEBHOOK_URL: $(TEAMS_WEBHOOK_URL)
```
{% endraw %}

### Manual Execution

```bash
# Generate today's standup report
cwf workflow run daily-standup

# Generate for specific date
cwf workflow run daily-standup --date 2025-01-15

# Dry run (preview without posting)
cwf workflow run daily-standup --dry-run
```

## Integration with Team Tools

### Slack Integration
Set environment variable:
```bash
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
```

### Microsoft Teams Integration
Set environment variable:
```bash
export TEAMS_WEBHOOK_URL="https://outlook.office.com/webhook/YOUR/WEBHOOK/URL"
```

## Success Criteria

- ✅ Report generated every weekday morning
- ✅ Delivered to team channels within 5 minutes
- ✅ Blockers clearly highlighted
- ✅ Team members know what others are working on
- ✅ Sprint progress visible at a glance

## Configuration

**Agents Used:**
{% if config.is_agent_enabled('scrum-master') %}- Scrum Master (report generation and formatting){% endif %}

**Report Schedule:**
- **Daily**: Weekdays at 9 AM
- **Duration**: < 1 minute to generate
- **Distribution**: Slack/Teams/Email

**Work Item Types Tracked:**
- {{ work_tracking.work_item_types.story or 'User Story' }}
- {{ work_tracking.work_item_types.task or 'Task' }}
- {{ work_tracking.work_item_types.bug or 'Bug' }}

---

*Generated by Trustable AI Workbench for {{ project.name }}*
