# Pm Status Report

> Comprehensive Huly project status report for stakeholders. Includes executive summary, key metrics, milestones, velocity trend, team performance, exhaustive task list grouped by component and broken down by status, bottlenecks, risks, quality, documentation, and recommendations. Trigger on: /pm-status-report, 'full project status', 'comprehensive status report', 'weekly status report', 'project report for PROJ', 'status report'.

- Skill: `yotharit/pm-status-report` (Agent Skill)
- Install (CLI): `npx skillmds@latest add yotharit/pm-status-report`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yotharit/pm-status-report/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: yotharit (https://skillmd.com/u/yotharit)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/yotharit/pm-status-report

---


# /pm-status-report

Stakeholder-grade comprehensive status report for a Huly tracker project. ~10 sections including an exhaustive component-grouped task list. **Read-only**, no writes to Huly.

**Requires** the `huly` MCP server.

## Args

```
/pm-status-report <PROJECT> [--period 7d|30d|sprint]
```

- `PROJECT` — identifier or `_id`. **Required.**
- `--period` — reporting window:
  - `7d` (default) — last 7 days
  - `30d` — last 30 days
  - `sprint` — auto-detect the active milestone (`status == 1`); use its start (`createdOn` of milestone) → `target_date` as the window

## Tools called

Run in two waves. Wave 1 (parallel) gathers the dataset; wave 2 fans out for relations / supplementary sets.

**Wave 1:**
1. `huly_get_project` `{ project }` — name, identifier, archived flag.
2. `huly_list_statuses` `{ project }` — `_id` → name + category map; defines the **status column order** for the breakdown.
3. `huly_list_components` `{ project }` — `_id` → label map.
4. `huly_list_issues` `{ project, limit: 500 }` — main dataset.
5. `huly_list_milestones` `{ project }` — full milestone state.
6. `huly_get_detailed_time_report` `{ project, from: <period start> }` — effort in period, grouped by issue + assignee.
7. `huly_list_time_spend_reports` `{ project, from: now − 8 weeks }` — velocity trend.
8. `huly_list_documents` (only if a teamspace is known — typically skipped unless the user provided one) for doc coverage.
9. `huly_list_test_runs` — only if a QMS test project shares the project's name; otherwise skip.

**Wave 2:**
- For each in-progress issue: nothing — instead, compute `blocks` counts in a single local pass (see "Bottleneck computation" below) over the wave-1 dataset to avoid 500× calls.

## Local computation

### Lookup maps
- `statusMap: id → { name, category, rank }` — preserve `huly_list_statuses` order for column rendering.
- `componentMap: id → label` plus a synthetic `"__uncategorized__" → "Uncategorized"` bucket.

### Group issues by component, then by status
```
for issue in issues:
  comp = componentMap[issue.component] or "Uncategorized"
  status = statusMap[issue.status].name
  buckets[comp][status].append(issue)
```

Within each `(comp, status)` bucket, sort by:
1. Priority (urgent → low → none)
2. `modifiedOn` desc

### Bottleneck count
```
blocksByIssue = {}  # issue._id → list of blocked issue identifiers
for issue in issues:
  for rel in issue.relations or []:
    if rel._class == "tracker:relation:Blocks":
      blocksByIssue.setdefault(rel.relatedTo, []).append(issue.identifier)
```
Top bottlenecks = those with `len(blockers) >= 2`, sorted by descending count.

### Velocity
- Bucket `huly_list_time_spend_reports` entries into 7-day windows for the last 8 weeks based on `date`.
- Count of issues closed per week = issues whose `modifiedOn` falls in week AND `statusMap[issue.status].category == "tracker:statusCategory:Completed"`.

### Team performance
For each assignee (group by `assignee`):
- Active = open issues currently assigned (status not done/cancelled).
- Closed in period = issues closed (by `modifiedOn` + done category) in the period.
- Time in period = sum of report.value where `report.createdBy == assignee` and `date >= period_start`.
- Avg cycle = mean `(modifiedOn - createdOn)/86_400_000` over period-closed issues.
- On-time = % of period-closed issues where `dueDate == null OR modifiedOn <= dueDate`.

### Risks
Reuse the rules from `pm-risks` (see that SKILL.md). Show only the counts and top 3 in this report; full detail belongs in `/pm-risks`.

### Recommendations
Derive 3–5 lines from:
- Top HIGH risk → "Assign / re-scope / unblock …"
- Largest stale component → "Review status of `<Component>` — N issues stale"
- Worst on-time assignee → "Check in with `<name>` (on-time %)"
- Documentation staleness (if doc data available) → "Refresh `<doc>` (Nd stale)"

## Output structure

```
═══════════════════════════════════════════════════════
  PROJECT STATUS REPORT — [Name] ([IDENT])
  Period: [YYYY-MM-DD] → [YYYY-MM-DD] ([period label])
  Generated: [YYYY-MM-DD]
═══════════════════════════════════════════════════════

EXECUTIVE SUMMARY
─────────────────
[2–3 sentence narrative covering: this-period delivery vs prior, active
sprint state, top 1–2 risks.]

KEY METRICS
───────────
                              This period   Prev period   Δ
  Issues created                  [n]          [n]        [±%]
  Issues closed                   [n]          [n]        [±%]
  Net backlog change              [±n]         [±n]        —
  Time logged (hours)           [h]          [h]          [±%]
  Active contributors             [n]          [n]        [±%]
  Avg cycle time (days)         [d]          [d]          [±%]

SCOPE & PROGRESS
────────────────
  Total issues: [N]
  ├─ Done:          [n]  ([%])
  ├─ In-progress:   [n]  ([%])
  ├─ In-review:     [n]  ([%])
  ├─ Backlog:       [n]  ([%])
  └─ Cancelled:     [n]  ([%])

  Scope by priority:
    🔥 Urgent  [n]  ([n] unassigned ⚠ if >0)
    ⬆  High   [n]  ([n] in-progress)
    →  Medium [n]
    ⬇  Low    [n]
    —  None   [n]

MILESTONES
──────────
  ✓ [label]    completed [date] ([done]/[total] done, 100%)
  ◐ [label]    target [date], [N]d left
               [total] issues · [done] done · [open] open · [%]%
               Required pace: [r]/day · Actual: [a]/day
               [⚠ AT RISK — recommend re-scope] if applicable
  ○ [label]    target [date], [N]d left, [done]/[total]

VELOCITY (last 8 weeks — issues closed)
───────────────────────────────────────
  Week of [date]: [bar]  [n]
  ...
  Week of [date]: [bar]  [n]  ← current
  Trend: [±n] issues/week ([direction])

TEAM PERFORMANCE
────────────────
  Member        Active  Closed/wk  Time/wk  Avg cycle  On-time
  [name]          [n]     [n]       [h]h     [d]d      [%]
  ...
  unassigned     [n]      —          —        —         —

  [⚠ flags for: high unassigned count, low on-time per member, no time logged]

═══════════════════════════════════════════════════════
  ALL TASKS BY COMPONENT  (full breakdown)
═══════════════════════════════════════════════════════

COMPONENT: [label]                                ([N] issues)
──────────────────────────────────────────────────────
  [Status name 1] ([n])
    [PROJ-N]  [priority icon] [priority label]  [title]    @[assignee]  [age info]
    ...
  [Status name 2] ([n])
    ...

COMPONENT: [next label]                           ([N] issues)
──────────────────────────────────────────────────────
  ...

UNCATEGORIZED                                     ([N] issues)
──────────────────────────────────────────────────────
  ...

═══════════════════════════════════════════════════════

BOTTLENECKS
───────────
  [PROJ-N]  [title]              blocks [n] · [stuck Nd|in-review|...] · @[assignee]
  ...

RISKS  (see /pm-risks for full detail)
─────
  🔴 [n] HIGH    [top 1–2, comma-separated]
  🟡 [n] MEDIUM  [counts only]
  🟢 [n] WATCH   [counts only]

QUALITY  (only if test data was found)
───────
  Latest run: [name] · [n] cases · [n] passed · [n] failed · [n] blocked
  Pass rate: [%] (target [%])
  Open bugs by priority: urgent [n] · high [n] · medium [n]

COMPONENTS  (activity snapshot)
──────────
  [label]     [n] open  · last activity [Nd]
  ...

DOCUMENTATION  (only if doc data available)
─────────────
  [n] linked teamspaces · [n] documents · [n] updated this period
  [⚠ flags for stale docs >30d]

RECOMMENDATIONS
───────────────
  1. [derived line]
  2. [derived line]
  3. [derived line]
```

## Row format inside "All Tasks by Component"

```
[IDENTIFIER]  [icon] [priority]  [title (truncate to 50 chars + … if longer)]   @[assignee or —]   [age]
```

- **Priority icons:** 🔥 urgent · ⬆ high · → med · ⬇ low · — none.
- **Age column:**
  - For non-done/cancelled: number of days since `modifiedOn`, e.g. `2d`. If > 7d and in-progress, append ⚠.
  - For Done: `closed [MM-DD]`.
  - For Cancelled: `cancelled [MM-DD]`.
- **Assignee:** prefer display name from `huly_workspace_info` members lookup; fall back to email; `—` if null.

## Output sizing

- Status order within each component follows the project's status order (from `huly_list_statuses`).
- Show every issue in every status bucket — **no truncation**, this is the comprehensive view.
- **If project > 500 issues:** show a warning at the top of the report: `⚠ Showing first 500 issues by modifiedOn — N additional issues omitted. Filter by milestone or component to narrow.`

## Edge cases

- **No active milestone for `--period sprint`** — fall back to `--period 7d` and add a note: `No active sprint detected; using 7d window.`
- **Project with no components** — the entire breakdown collapses to a single `UNCATEGORIZED` section. That's fine.
- **No prior period** for delta arithmetic — show `—` in Δ column rather than 100%.
- **Status with zero issues** in a component — omit that status sub-bucket entirely (don't print `Done (0)`).
- **Long component label** — wrap to 30 chars in the header line.

## Don't

- Don't write anything to Huly (no docs, no comments, no field updates).
- Don't truncate the by-component task list — the user explicitly wants the full breakdown.
- Don't dump raw JSON.
- Don't call `huly_list_issue_relations` per-issue — compute the `blocks` map locally from the dataset.
- Don't include sections whose underlying data was empty (e.g. omit QUALITY entirely if no test runs found, omit DOCUMENTATION if no teamspace was supplied).

