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).
Recommended Classification Criteria
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
Conservative Approach (Recommended)
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)
-
Implement conservative filter in flow metrics calculator
- Location:
src/calculators/flow_metrics.py - Add
is_non_work_issue()function - Update velocity and time calculations
- Location:
-
Add metrics reporting
- Report both raw and adjusted metrics
- Show count of excluded issues
- Add explanation in output
-
Update team config
- Add
exclude_non_work_issuesflag per team - Default:
True(exclude)
- Add
Phase 2: Data Enhancement (Next Sprint)
-
Enhance JIRA data fetching
- Include
resolutionfield in API query - Add to domain model
- Store in JSON cache
- Include
-
Add resolution-based filtering
- Implement in flow/DORA calculators
- Update non-work detection logic
Phase 3: Validation (Following Sprint)
-
Analyze other teams (O2C, ACQREG, SSH, LGMT)
- Validate pattern consistency
- Adjust thresholds if needed
-
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
-
Threshold Validation: Is 120 days the right threshold for "backlog cleanup"?
- Alternative: 90 days, 180 days?
-
Metric Reporting: Should we show both raw and adjusted metrics?
- Transparency vs. simplicity
-
Team Consistency: Should all teams use the same criteria?
- Or allow per-team customization?
-
Spike Handling: Should Spikes/Research tasks be excluded?
- They are planned work, but produce no deliverable
-
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
Related Files
- 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).