Skip to content

Non-Work Issue Analysis - Final Recommendations

Date: 2025-11-26 Team: UAS (User Authentication Services) Analyst: Claude Code Dataset: 238 total issues, 175 completed


Problem Statement

Currently, all completed JIRA issues count toward velocity and time-based metrics (lead time, cycle time), regardless of whether actual development work was performed. This includes:

  • Issues marked as "Won't Fix" or "Duplicate"
  • Issues that never entered development
  • Backlog cleanup activities

This skews metrics and makes it difficult to understand true team productivity.


Key Findings

1. Non-Work Issue Prevalence

21.7% (38 out of 175) of completed issues never entered "In Progress" status.

These issues went directly from "To Do" → "Done", indicating no development work occurred.

2. Pattern Characteristics

Lead Time Distribution for Skip Pattern Issues:

Bucket Count % of Skip Pattern
< 1 day 1 2.6%
1-7 days 1 2.6%
7-30 days 3 7.9%
> 30 days 33 86.8%

Key Insight: 86.8% of skip pattern issues sat in the backlog for over 30 days before being closed. Average lead time: 124.26 days (vs. 54.53 days for all issues).

3. Issue Types Affected

Issue Type Count % of Skip Pattern
Task 20 52.6%
TechTask 8 21.1%
Sub-task 6 15.8%
Bug 3 7.9%
Epic 1 2.6%

4. Quick Completions (< 1 day) Breakdown

  • With skip pattern (To Do → Done): 1 issue
  • With In Progress: 8 issues (likely legitimate quick fixes)

Conclusion: Very short lead times alone are NOT a good indicator of non-work. Most non-work issues actually have LONG lead times (backlog cleanup).


PRIMARY RECOMMENDATION: Workflow-Based Filter

Exclude from velocity/time metrics if:

Issue meets ALL of:
1. Never entered "In Progress" status (skip pattern: To Do → Done)
2. AND one of:
   a. Lead time < 1 day (immediate rejection), OR
   b. Lead time > 120 days (backlog cleanup)

Implementation Priority: HIGH Data Available: YES (can implement immediately) Estimated Impact: ~5-10 issues (2.9-5.7% of completed)

SECONDARY RECOMMENDATION: Resolution-Based Filter

Exclude if resolution field equals: - "Won't Do" / "Won't Fix" - "Duplicate" - "Cannot Reproduce" - "Invalid" - "Declined" - "Abandoned"

Implementation Priority: MEDIUM Data Available: NO (requires data model enhancement) Estimated Impact: Unknown until data available

TERTIARY RECOMMENDATION: Issue Type Filter

Optionally exclude: - "Spike" (research, no deliverable) - "Research" (investigation, no deliverable)

Implementation Priority: LOW Data Available: YES Estimated Impact: Small (few of these in dataset)


Metric Impact Analysis

Exclude: Issues with skip pattern AND (lead time < 1 day OR > 120 days)

Metric Current Adjusted Change
Velocity 175 ~170 -2.9%
Avg Lead Time 54.53 days ~52 days -4.6%
Median Lead Time 21.99 days ~21 days -4.5%

Aggressive Approach (All Skip Patterns)

Exclude: All issues that never entered "In Progress"

Metric Current Adjusted Change
Velocity 175 137 -21.7%
Avg Lead Time 54.53 days ~45 days -17.5%
Median Lead Time 21.99 days ~18 days -18.2%

Implementation Plan

Phase 1: Immediate (This Week)

  1. Implement conservative filter in flow metrics calculator

    • Location: src/calculators/flow_metrics.py
    • Add is_non_work_issue() function
    • Update velocity and time calculations
  2. Add metrics reporting

    • Report both raw and adjusted metrics
    • Show count of excluded issues
    • Add explanation in output
  3. Update team config

    • Add exclude_non_work_issues flag per team
    • Default: True (exclude)

Phase 2: Data Enhancement (Next Sprint)

  1. Enhance JIRA data fetching

    • Include resolution field in API query
    • Add to domain model
    • Store in JSON cache
  2. Add resolution-based filtering

    • Implement in flow/DORA calculators
    • Update non-work detection logic

Phase 3: Validation (Following Sprint)

  1. Analyze other teams (O2C, ACQREG, SSH, LGMT)

    • Validate pattern consistency
    • Adjust thresholds if needed
  2. Stakeholder review

    • Present findings to team leads
    • Gather feedback on classification criteria
    • Adjust based on domain knowledge

Code Implementation

1. Non-Work Detection Function

def is_non_work_issue(issue: Issue, transitions: List[StatusTransition]) -> bool:
    """
    Determine if issue should be excluded from velocity/time metrics.

    An issue is considered non-work if it was closed without development work:
    - Never entered In Progress status
    - AND very quick close (< 1 day) OR very old backlog cleanup (> 120 days)

    Args:
        issue: Domain Issue object
        transitions: List of status transitions

    Returns:
        True if issue is non-work and should be excluded
    """
    # Check if issue ever entered in-progress
    ever_in_progress = any(
        get_status_category(t.to_status) == 'in_progress'
        for t in transitions
    )

    # If it never entered in-progress and is resolved
    if not ever_in_progress and issue.resolved_at:
        # Calculate lead time
        lead_time_days = (issue.resolved_at - issue.created_at).total_seconds() / 86400

        # Exclude if very quick (< 1 day) or very old (> 120 days)
        if lead_time_days < 1 or lead_time_days > 120:
            return True

    return False

2. Update Flow Metrics Calculator

# In src/calculators/flow_metrics.py

def calculate_flow_metrics(self, issues: List[Issue]) -> FlowMetrics:
    """Calculate Flow Framework metrics, excluding non-work issues."""

    # Filter to completed issues
    completed_issues = [i for i in issues if self._is_done(i)]

    # NEW: Filter out non-work issues
    work_issues = [
        i for i in completed_issues
        if not is_non_work_issue(i, i.transitions)
    ]

    # Calculate metrics on work_issues instead of completed_issues
    velocity = len(work_issues)

    # ... rest of calculations

    return FlowMetrics(
        velocity=velocity,
        velocity_raw=len(completed_issues),  # NEW: Track raw count
        non_work_count=len(completed_issues) - len(work_issues),  # NEW
        # ... other metrics
    )

3. Update Domain Models

# In src/domain/models.py

@dataclass
class FlowMetrics:
    """Flow Framework metrics for a team."""

    # Existing fields
    velocity: int
    load: int
    flow_time_avg: float
    flow_time_median: float
    flow_time_p85: float
    flow_efficiency: float

    # NEW: Non-work tracking
    velocity_raw: int  # Total completed (including non-work)
    non_work_count: int  # Number of non-work issues excluded

    # Distribution
    distribution: Dict[str, int]

Reporting Template

Example Output

Flow Metrics - UAS Team
=======================

Velocity (Work Issues): 137 issues
  Excluded (Non-Work): 38 issues (21.7%)
  Total Completed: 175 issues

Lead Time (Work Issues):
  Average: 45.2 days
  Median: 18.1 days
  P85: 89.5 days

Note: Non-work issues are those that never entered In Progress and were either
      closed immediately (< 1 day) or were backlog cleanup (> 120 days).

Questions for Stakeholders

  1. Threshold Validation: Is 120 days the right threshold for "backlog cleanup"?

    • Alternative: 90 days, 180 days?
  2. Metric Reporting: Should we show both raw and adjusted metrics?

    • Transparency vs. simplicity
  3. Team Consistency: Should all teams use the same criteria?

    • Or allow per-team customization?
  4. Spike Handling: Should Spikes/Research tasks be excluded?

    • They are planned work, but produce no deliverable
  5. Bug Handling: 3 bugs in skip pattern - acceptable?

    • May indicate quality issues in bug reporting

Success Criteria

Implementation Complete When: 1. Non-work filter implemented in calculators 2. Both raw and adjusted metrics reported 3. Excluded issue count tracked and displayed 4. All teams analyzed for pattern validation 5. Stakeholder approval on criteria

Metrics Improved When: 1. Velocity better reflects actual work completed 2. Lead time represents actual development time 3. Team comparisons more meaningful 4. Trend analysis less noisy


  • Analysis script: /Users/maikel.lammers/projects/jira-kpi-system/analyze_non_work_issues.py
  • Detailed results: /Users/maikel.lammers/projects/jira-kpi-system/non_work_analysis_results.md
  • Flow calculator: /Users/maikel.lammers/projects/jira-kpi-system/src/calculators/flow_metrics.py
  • Domain models: /Users/maikel.lammers/projects/jira-kpi-system/src/domain/models.py

Next Action: Review with team leads and implement Phase 1 (conservative filter).