agile-sprint-planning

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Agile Sprint Planning

Agile Sprint规划

Overview

概述

Agile sprint planning provides a structured approach to organize work into time-boxed iterations, enabling teams to deliver value incrementally while maintaining flexibility and responding to change.
Agile Sprint规划提供了一种结构化方法,将工作组织为时间盒式迭代,使团队能够在保持灵活性和响应变化的同时逐步交付价值。

When to Use

适用场景

  • Starting a new sprint cycle
  • Defining sprint goals and objectives
  • Estimating user stories and tasks
  • Managing sprint backlog prioritization
  • Handling mid-sprint changes or scope adjustments
  • Preparing sprint reviews and retrospectives
  • Training team members on Agile practices
  • 启动新的Sprint周期
  • 定义Sprint目标与宗旨
  • 估算user stories与任务
  • 管理sprint backlog的优先级排序
  • 处理Sprint中期的变更或范围调整
  • 准备Sprint评审与回顾会议
  • 向团队成员培训Agile实践方法

Instructions

操作指南

1. Pre-Sprint Planning

1. Sprint前规划

markdown
undefined
markdown
undefined

Sprint Planning Checklist

Sprint Planning Checklist

1-2 Days Before Planning Meeting

1-2 Days Before Planning Meeting

  • Groom product backlog (ensure top items are detailed)
  • Update user story acceptance criteria
  • Identify dependencies and blockers
  • Prepare estimates from previous sprints
  • Review team velocity (average story points per sprint)
  • Identify team availability/absences
  • Prepare sprint goals draft
  • Groom product backlog (ensure top items are detailed)
  • Update user story acceptance criteria
  • Identify dependencies and blockers
  • Prepare estimates from previous sprints
  • Review team velocity (average story points per sprint)
  • Identify team availability/absences
  • Prepare sprint goals draft

Information to Gather

Information to Gather

  • Product Owner priorities
  • Team capacity (working hours available)
  • Previous sprint metrics
  • Upcoming holidays or interruptions
  • Technical debt items to address
undefined
  • Product Owner priorities
  • Team capacity (working hours available)
  • Previous sprint metrics
  • Upcoming holidays or interruptions
  • Technical debt items to address
undefined

2. Sprint Planning Meeting Structure

2. Sprint规划会议结构

javascript
// Example sprint planning agenda and execution

class SprintPlanner {
  constructor(team, sprintLength = 2) {
    this.team = team;
    this.sprintLength = sprintLength; // weeks
    this.userStories = [];
    this.sprintGoal = '';
    this.capacity = 0;
  }

  calculateTeamCapacity() {
    // Capacity = available hours - meetings - buffer
    const workHours = 40; // per person per week
    const meetingHours = 5; // estimated standups, retros, etc.
    const bufferPercent = 0.2; // 20% buffer for interruptions

    const capacityPerPerson = (workHours - meetingHours) * (1 - bufferPercent);
    this.capacity = capacityPerPerson * this.team.length * this.sprintLength;

    return this.capacity;
  }

  conductPlanningMeeting() {
    return {
      part1: {
        duration: '15 minutes',
        activity: 'Product Owner presents sprint goal',
        deliverable: 'Team understands business objective'
      },
      part2: {
        duration: '45-60 minutes',
        activity: 'Team discusses and estimates user stories',
        deliverable: 'Prioritized sprint backlog with story points'
      },
      part3: {
        duration: '15 minutes',
        activity: 'Team commits to sprint goal',
        deliverable: 'Formal sprint backlog committed'
      }
    };
  }

  createSprintBacklog(stories, capacity) {
    let currentCapacity = capacity;
    const sprintBacklog = [];

    for (let story of stories) {
      if (currentCapacity >= story.points) {
        sprintBacklog.push({
          ...story,
          status: 'planned',
          sprint: this.currentSprint
        });
        currentCapacity -= story.points;
      }
    }

    return {
      goal: this.sprintGoal,
      backlog: sprintBacklog,
      remainingCapacity: currentCapacity,
      utilization: ((capacity - currentCapacity) / capacity * 100).toFixed(1) + '%'
    };
  }
}
javascript
// Example sprint planning agenda and execution

class SprintPlanner {
  constructor(team, sprintLength = 2) {
    this.team = team;
    this.sprintLength = sprintLength; // weeks
    this.userStories = [];
    this.sprintGoal = '';
    this.capacity = 0;
  }

  calculateTeamCapacity() {
    // Capacity = available hours - meetings - buffer
    const workHours = 40; // per person per week
    const meetingHours = 5; // estimated standups, retros, etc.
    const bufferPercent = 0.2; // 20% buffer for interruptions

    const capacityPerPerson = (workHours - meetingHours) * (1 - bufferPercent);
    this.capacity = capacityPerPerson * this.team.length * this.sprintLength;

    return this.capacity;
  }

  conductPlanningMeeting() {
    return {
      part1: {
        duration: '15 minutes',
        activity: 'Product Owner presents sprint goal',
        deliverable: 'Team understands business objective'
      },
      part2: {
        duration: '45-60 minutes',
        activity: 'Team discusses and estimates user stories',
        deliverable: 'Prioritized sprint backlog with story points'
      },
      part3: {
        duration: '15 minutes',
        activity: 'Team commits to sprint goal',
        deliverable: 'Formal sprint backlog committed'
      }
    };
  }

  createSprintBacklog(stories, capacity) {
    let currentCapacity = capacity;
    const sprintBacklog = [];

    for (let story of stories) {
      if (currentCapacity >= story.points) {
        sprintBacklog.push({
          ...story,
          status: 'planned',
          sprint: this.currentSprint
        });
        currentCapacity -= story.points;
      }
    }

    return {
      goal: this.sprintGoal,
      backlog: sprintBacklog,
      remainingCapacity: currentCapacity,
      utilization: ((capacity - currentCapacity) / capacity * 100).toFixed(1) + '%'
    };
  }
}

3. Story Point Estimation

3. 故事点估算

python
undefined
python
undefined

Story point estimation using Planning Poker approach

Story point estimation using Planning Poker approach

class StoryEstimation: # Fibonacci sequence for estimation ESTIMATE_OPTIONS = [1, 2, 3, 5, 8, 13, 21, 34]
@staticmethod
def calculate_story_points(complexity, effort, risk):
    """
    Estimate story points based on multiple factors
    Factors should be rated 1-5
    """
    base_points = (complexity * effort) / 5
    risk_multiplier = 1 + (risk * 0.1)
    estimated_points = base_points * risk_multiplier

    # Round to nearest Fibonacci number
    for estimate in StoryEstimation.ESTIMATE_OPTIONS:
        if estimated_points <= estimate:
            return estimate

    return StoryEstimation.ESTIMATE_OPTIONS[-1]

@staticmethod
def conduct_planning_poker(team_estimates):
    """
    Handle Planning Poker consensus process
    """
    estimates = sorted(team_estimates)
    median = estimates[len(estimates) // 2]

    # If significant disagreement, discuss and re-estimate
    if estimates[-1] - estimates[0] > 5:
        return {
            'consensus': False,
            'median': median,
            'low': estimates[0],
            'high': estimates[-1],
            'action': 'Discuss and re-estimate'
        }

    return {'consensus': True, 'estimate': median}
class StoryEstimation: # Fibonacci sequence for estimation ESTIMATE_OPTIONS = [1, 2, 3, 5, 8, 13, 21, 34]
@staticmethod
def calculate_story_points(complexity, effort, risk):
    """
    Estimate story points based on multiple factors
    Factors should be rated 1-5
    """
    base_points = (complexity * effort) / 5
    risk_multiplier = 1 + (risk * 0.1)
    estimated_points = base_points * risk_multiplier

    # Round to nearest Fibonacci number
    for estimate in StoryEstimation.ESTIMATE_OPTIONS:
        if estimated_points <= estimate:
            return estimate

    return StoryEstimation.ESTIMATE_OPTIONS[-1]

@staticmethod
def conduct_planning_poker(team_estimates):
    """
    Handle Planning Poker consensus process
    """
    estimates = sorted(team_estimates)
    median = estimates[len(estimates) // 2]

    # If significant disagreement, discuss and re-estimate
    if estimates[-1] - estimates[0] > 5:
        return {
            'consensus': False,
            'median': median,
            'low': estimates[0],
            'high': estimates[-1],
            'action': 'Discuss and re-estimate'
        }

    return {'consensus': True, 'estimate': median}

Example usage

Example usage

print(StoryEstimation.calculate_story_points( complexity=3, # Medium complexity effort=2, # Low effort risk=1 # Low risk )) # Output: 3 points
undefined
print(StoryEstimation.calculate_story_points( complexity=3, # Medium complexity effort=2, # Low effort risk=1 # Low risk )) # Output: 3 points
undefined

4. Sprint Goal Definition

4. Sprint目标定义

yaml
Sprint Goal Template:

Sprint: Sprint 23 (Nov 7 - Nov 20)

Goal Statement: |
  Enable users to manage multiple payment methods with a secure,
  intuitive interface that reduces checkout time by 40%

Success Criteria:
  - Payment method management UI implemented
  - 95% test coverage on payment logic
  - Performance: <200ms payment processing
  - Zero critical security issues
  - Feature released to 20% of users for A/B testing

Team Commitment: 89 story points
Expected Velocity: 85-95 points

Key Risks:
  - Payment gateway API changes
  - Security compliance requirements
  - Integration complexity

Acceptance:
  - All criteria met
  - Feature deployed to staging
  - Security review approved
  - Team and PO sign-off
yaml
Sprint Goal Template:

Sprint: Sprint 23 (Nov 7 - Nov 20)

Goal Statement: |
  Enable users to manage multiple payment methods with a secure,
  intuitive interface that reduces checkout time by 40%

Success Criteria:
  - Payment method management UI implemented
  - 95% test coverage on payment logic
  - Performance: <200ms payment processing
  - Zero critical security issues
  - Feature released to 20% of users for A/B testing

Team Commitment: 89 story points
Expected Velocity: 85-95 points

Key Risks:
  - Payment gateway API changes
  - Security compliance requirements
  - Integration complexity

Acceptance:
  - All criteria met
  - Feature deployed to staging
  - Security review approved
  - Team and PO sign-off

5. Daily Standup Management

5. Daily Standup管理

javascript
// Daily standup structure and tracking

class DailyStandup {
  constructor(team) {
    this.team = team;
    this.standups = [];
  }

  conductStandup(date) {
    const standup = {
      date,
      startTime: new Date(),
      participants: [],
      timeboxed: true,
      durationMinutes: 15
    };

    for (let member of this.team) {
      standup.participants.push({
        name: member.name,
        yesterday: member.getYesterdayWork(),
        today: member.getPlanForToday(),
        blockers: member.getBlockers(),
        helpNeeded: member.getHelpNeeded()
      });
    }

    return {
      standup,
      followUpActions: this.identifyFollowUps(standup),
      blockerResolutionOwners: this.assignBlockerOwners(standup)
    };
  }

  identifyFollowUps(standup) {
    return standup.participants
      .filter(p => p.blockers.length > 0)
      .map(p => ({
        owner: p.name,
        blockers: p.blockers,
        deadline: new Date(Date.now() + 24 * 60 * 60 * 1000)
      }));
  }
}
javascript
// Daily standup structure and tracking

class DailyStandup {
  constructor(team) {
    this.team = team;
    this.standups = [];
  }

  conductStandup(date) {
    const standup = {
      date,
      startTime: new Date(),
      participants: [],
      timeboxed: true,
      durationMinutes: 15
    };

    for (let member of this.team) {
      standup.participants.push({
        name: member.name,
        yesterday: member.getYesterdayWork(),
        today: member.getPlanForToday(),
        blockers: member.getBlockers(),
        helpNeeded: member.getHelpNeeded()
      });
    }

    return {
      standup,
      followUpActions: this.identifyFollowUps(standup),
      blockerResolutionOwners: this.assignBlockerOwners(standup)
    };
  }

  identifyFollowUps(standup) {
    return standup.participants
      .filter(p => p.blockers.length > 0)
      .map(p => ({
        owner: p.name,
        blockers: p.blockers,
        deadline: new Date(Date.now() + 24 * 60 * 60 * 1000)
      }));
  }
}

Best Practices

最佳实践

✅ DO

✅ 建议做法

  • Base capacity on actual team velocity from past sprints
  • Include buffer time for interruptions and support work
  • Focus sprint goal on business value, not technical tasks
  • Timeboxe planning meeting (2 hours max for 2-week sprint)
  • Include entire team in planning discussion
  • Break down large stories into smaller, manageable pieces
  • Track story points for velocity trending
  • Review and adjust estimates based on actual completion
  • Maintain consistent sprint length
  • Include retrospective improvements in planning
  • 根据过往Sprint的实际团队velocity确定容量
  • 预留缓冲时间以应对突发情况与支持工作
  • Sprint目标聚焦业务价值,而非技术任务
  • 为规划会议设置时间盒(2周Sprint最多2小时)
  • 让整个团队参与规划讨论
  • 将大型user story拆分为更小、可管理的模块
  • 跟踪故事点以了解velocity趋势
  • 根据实际完成情况回顾并调整估算
  • 保持一致的Sprint时长
  • 在规划中纳入回顾会议提出的改进措施

❌ DON'T

❌ 避免做法

  • Plan for 100% capacity utilization
  • Skip story grooming before planning meeting
  • Add stories after sprint starts (unless emergency)
  • Let one person estimate for entire team
  • Use story points as employee performance metrics
  • Ignore team velocity trends
  • Plan without clear sprint goal
  • Force stories into sprints to match capacity numbers
  • Skip sprint planning to save time
  • Use planning poker results as final estimate without discussion
  • 按100%容量利用率规划
  • 跳过规划会议前的user story梳理
  • Sprint开始后添加新条目(紧急情况除外)
  • 让单人代替整个团队进行估算
  • 将故事点用作员工绩效指标
  • 忽视团队velocity趋势
  • 在没有明确Sprint目标的情况下进行规划
  • 为匹配容量数字强行将故事纳入Sprint
  • 为节省时间跳过Sprint规划
  • 不经过讨论就将规划扑克结果作为最终估算

Sprint Planning Tips

Sprint规划技巧

  • Keep stories to 5-13 points (break larger stories down)
  • Maintain 85-90% capacity utilization (leave buffer for interruptions)
  • Document sprint goal visibly (physical board or Jira)
  • Track velocity over 5-10 sprints to identify trends
  • Use historical data for better estimates
  • Celebrate sprint successes in reviews
  • Identify and address estimation biases
  • Adjust processes based on retrospective feedback
  • 将故事控制在5-13个故事点(拆分大型故事)
  • 保持85-90%的容量利用率(预留缓冲时间应对突发情况)
  • 将Sprint目标可视化展示(实体看板或Jira)
  • 跟踪5-10个Sprint的velocity以识别趋势
  • 利用历史数据进行更准确的估算
  • 在评审会议中庆祝Sprint成果
  • 识别并解决估算偏差
  • 根据回顾反馈调整流程