/pm-risks
Risk radar for a Huly tracker project. Surfaces issues / milestones that need PM attention this week. Output only — never writes to Huly.
Requires the huly MCP server.
Args
/pm-risks <PROJECT> [--stale-days 7] [--block-threshold 3]
PROJECT— identifier or_id. Required. If missing, ask.--stale-days— threshold for "stuck" rule. Default7.--block-threshold— minimum dependents for the "bottleneck" rule. Default3.
Steps
huly_list_statuses{ project }— map status_id→ name + category, identify which statuses aredone/cancelled.huly_list_issues{ project, limit: 500 }— full dataset.huly_list_milestones{ project }— milestone status + target dates.huly_get_detailed_time_report{ project }— used for over-budget rule.- For top in-progress / high-priority issues, call
huly_list_issue_relations{ identifier }to count how many issues each one blocks. (Only fan out for the top ~30 candidates to keep latency reasonable.)
Risk rules
Apply each rule against the dataset. Each rule produces zero or more risk records with {severity, rule, identifier|milestone, title, details}.
| Severity | Rule | Condition |
|---|---|---|
| 🔴 HIGH | Overdue | dueDate < now AND status not in done/cancelled |
| 🔴 HIGH | Milestone at risk | Milestone status == 1 (in-progress) AND target_date < now + 7d AND > 30% of its issues still open |
| 🔴 HIGH | Critical bottleneck | Issue blocks ≥ block-threshold * 2 other issues AND modifiedOn > stale-days days ago |
| 🟡 MED | Unassigned high-priority | priority in (1=urgent, 2=high) AND assignee == null |
| 🟡 MED | Stuck | status in-progress (category Started) AND modifiedOn > stale-days days ago |
| 🟡 MED | Bottleneck | Issue blocks ≥ block-threshold others (and not already in critical) |
| 🟢 WATCH | Over-budget | estimation > 0 AND total logged time / estimation > 1.5 |
| 🟢 WATCH | Sprint slipping | Active milestone where required pace > 2× actual pace this week |
(Pace = issues per remaining day to hit 100% open-closed by target_date; actual pace = issues closed in the last 7 days / 7.)
Severity ordering
Within each severity tier, sort by:
- Number of dependents (bottlenecks first).
- Days overdue / days stuck (descending).
- Priority (urgent → low).
Output format
Risks — [PROJECT] · [YYYY-MM-DD]
🔴 HIGH ([count])
1. [PROJ-N] [title] · overdue [n]d · @[assignee]
2. [Sprint name] at risk · [open]/[total] open · target in [n]d
3. [PROJ-N] [title] · blocks [n] issues · stuck [n]d
...
🟡 MEDIUM ([count])
[k]. [PROJ-N] [title] · urgent, unassigned
[k]. [PROJ-N] [title] · in-progress [n]d, no update
...
🟢 WATCH ([count])
[k]. [PROJ-N] [title] · est [n]h, logged [n]h ([×ratio])
...
Recommend:
• [1 line, derived from the top HIGH item]
• [1 line, derived from sprint risk if present]
• [1 line, derived from largest bottleneck]
If there are zero risks in a tier, omit the tier header entirely. If zero risks total, say:
Risks — [PROJECT] · [YYYY-MM-DD]
No active risks detected.
Scope: [n] open · [n] in-progress · sprint on pace.
Computation notes
- Relations check (bottleneck): the
is-blocked-bydirection comes from looking at OTHER issues' relations pointing at this one. Practical approach: for each issue, theblockscount = number of issues whoserelationsarray contains an entry with_class == 'tracker:relation:Blocks'ANDrelatedTo == thisIssue._id. Compute this in one pass over the full issue set rather than callinghuly_list_issue_relations500 times. - Days overdue / stuck: integer days, floor of
(now - timestamp) / 86_400_000. - Sprint pace:
open = issues in milestone with status not done/cancelled total = issues in milestone required_pace = open / max(1, days_until(target_date)) actual_pace = issues_closed_in_last_7d_in_milestone / 7
Edge cases
- Project with no milestones — skip the "milestone at risk" and "sprint slipping" rules cleanly. Don't fabricate.
- Issues with
dueDate == null— they can never trigger the overdue rule. That's correct. estimation == 0or null — over-budget rule does not apply. Skip.- Very large project (>500 issues) — note in the footer that the analysis covers the first 500 issues by
modifiedOn; suggest using a tighter project scope or a milestone filter.
Don't
- Don't call any
huly_create_*,huly_update_*, orhuly_delete_*tool. - Don't write to a teamspace, even if asked — direct the user to copy the output.
- Don't include risks for archived projects without explicit user confirmation.
- Don't speculate: if a rule fires on a flaky signal (e.g. modifiedOn just-now but assignee changed), mention the data source so the PM can verify.