# Milestone Risk Report

- **Command:** `lore milestone-risk [title]`
- **Confidence:** 78%
- **Tier:** 3
- **Status:** proposed
- **Effort:** medium — milestone + issue aggregation with scope change detection

## What

For each active milestone (or a specific one): show total issues, % closed, issues
added after milestone creation (scope creep), issues with no assignee, issues with
overdue due_date. Flag milestones where completion rate is below expected trajectory.

## Why

Milestone health is usually assessed by gut feel. This provides objective signals
from data already ingested. Project managers can spot risks early.

## Data Required

All exists today:
- `milestones` (title, state, due_date)
- `issues` (milestone_id, state, created_at, due_date, assignee)
- `issue_assignees` (for unassigned detection)

## Implementation Sketch

```sql
SELECT
    m.title,
    m.state,
    m.due_date,
    COUNT(*) as total_issues,
    SUM(CASE WHEN i.state = 'closed' THEN 1 ELSE 0 END) as closed,
    SUM(CASE WHEN i.state = 'opened' THEN 1 ELSE 0 END) as open,
    SUM(CASE WHEN i.created_at > m.created_at THEN 1 ELSE 0 END) as scope_creep,
    SUM(CASE WHEN ia.username IS NULL AND i.state = 'opened' THEN 1 ELSE 0 END) as unassigned,
    SUM(CASE WHEN i.due_date < DATE('now') AND i.state = 'opened' THEN 1 ELSE 0 END) as overdue
FROM milestones m
JOIN issues i ON i.milestone_id = m.id
LEFT JOIN issue_assignees ia ON ia.issue_id = i.id
WHERE m.state = 'active'
GROUP BY m.id;
```

Note: `created_at` comparison for scope creep is approximate — GitLab doesn't
expose when an issue was added to a milestone via its milestone_events.

Actually we DO have `resource_milestone_events` — use those for precise scope change
detection.

## Human Output

```
Milestone Risk Report

v2.0 (due Feb 15, 2025)
  Progress:  14/20 closed (70%)
  Scope:     +3 issues added after milestone start
  Risks:     2 issues overdue, 1 issue unassigned
  Status:    ON TRACK (70% complete, 60% time elapsed)

v2.1 (due Mar 30, 2025)
  Progress:  2/15 closed (13%)
  Scope:     +8 issues added after milestone start
  Risks:     5 issues unassigned
  Status:    AT RISK (13% complete, scope still growing)
```

## Downsides

- Milestone semantics vary wildly between teams
- "Scope creep" detection is noisy if teams batch-add issues to milestones
- due_date comparison assumes consistent timezone handling

## Extensions

- `lore milestone-risk --history` — show scope changes over time
- Velocity estimation: at current closure rate, will the milestone finish on time?
- Combine with label-flow for "how fast are milestone issues moving through workflow"
