From mypos-legal-copilot
Generate an overdue-tickets and team-productivity report for the myPOS Legal team. Pulls from Jira (open tickets, due dates, recent transitions, worklogs), prompts each lawyer for off-Jira hours, and files a .docx report to SharePoint via the n8n filing workflow. Triggered on demand by /legal-report. Use when the user asks for an overdue report, productivity report, who is behind, who is overloaded, or any "how is the team doing" question.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mypos-legal-copilot:legal-productivity-reportThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Tell the head of legal who is overloaded, who is behind, and what slipped past its deadline. Account for the fact that most of the team also does work that never makes it into Jira.
Tell the head of legal who is overloaded, who is behind, and what slipped past its deadline. Account for the fact that most of the team also does work that never makes it into Jira.
This skill is on demand only. It is not scheduled. The lawyer runs /legal-report whenever they want a snapshot.
$ARGUMENTS may include a date range like last_7_days, last_30_days (default), this_quarter, or an explicit YYYY-MM-DD..YYYY-MM-DD. If absent, use the last 30 calendar days.
JQL: project in (LEGAL, AIRD) AND duedate < now() AND statusCategory != Done ORDER BY duedate ASC
Fields: summary, assignee, duedate, priority, labels, created, status. Maximum 100 results.
For each overdue ticket compute:
days_overdue = today - duedateassignee_name (display name; if unassigned, mark "UNASSIGNED" -- this is a routing failure, not a productivity issue, and gets called out separately in Step 5)JQL: project in (LEGAL, AIRD) AND resolved >= "{range_start}" AND assignee is not EMPTY ORDER BY resolved DESC
For each lawyer in the roster (from knowledge/team-routing.md), count:
tickets_closed_in_rangeavg_time_to_close_days -- median is more useful than mean here; use the 50th percentile of (resolved - created)tickets_currently_open (statusCategory != Done assigned to them)tickets_in_progress (status = "In Progress")tickets_overdue_assigned (subset of 1a where they are the assignee)JQL: project in (LEGAL, AIRD) AND status changed during ("{range_start}", "{range_end}") ORDER BY updated DESC
For each lawyer, count distinct tickets where they triggered a transition. This catches work that doesn't end in Done (e.g., bouncing a ticket to Blocked, asking for clarification) but is still real work.
For each active lawyer in team-routing.md, ask the chat user (presumed to be the head of legal or whoever is running the report):
{lawyer_name} closed {tickets_closed_in_range} tickets in the last {range_days} days.
How many hours of off-Jira legal work did they put in over the same window?
(e.g., calls, drafting that didn't get filed, internal advice)
Enter a number, or "skip" to leave blank.
Wait for an answer per lawyer. If the user types skip or hits enter without a number, record off_jira_hours = null and tag the lawyer's section in the report with a (off-Jira hours not recorded) note.
This is intentionally a manual entry: per Atanas's preference, the team doesn't want timesheets or calendar parsing. The report's job is to make it easy to fill in, not to invent the data.
Tip for the head of legal: Before running this report, do a 5-minute scan of the team's calendars (private 1:1s, calls labelled "advice", "drafting", "review") to estimate the off-Jira number. The report will only be as honest as that input.
For each lawyer, mark:
load = tickets_currently_open -- raw numbervelocity = tickets_closed_in_range / range_days -- per-day rateoverdue_share = tickets_overdue_assigned / max(1, tickets_currently_open) -- 0.0 to 1.0composite_status (heuristic, see below)| Condition | Status |
|---|---|
overdue_share >= 0.30 | AT RISK -- slipping on deadlines |
load >= 12 AND overdue_share < 0.30 | OVERLOADED -- volume is high but they are still hitting dates |
load <= 3 AND velocity < 0.1 (less than 1 close per 10 days) AND off_jira_hours == null OR off_jira_hours < 10 | UNDER-UTILISED -- but flag for human check before raising it |
| Otherwise | OK |
Do NOT publish the UNDER-UTILISED label in the body of the report. Surface it only in a separate "for the head of legal -- private review section" near the end of the doc. Off-Jira work is invisible and we should not accuse anyone of being slow on the visible-Jira evidence alone.
The report is a .docx so it lands cleanly in SharePoint and the head of legal can mark it up.
Sections (in this order):
Legal team report -- {range_start} to {range_end}. Generated {today} by the Copilot.matter:* label, top 3)load)Use the docx skill (Skill(skill: "docx")) to render. Filename:
LEGAL-REPORT_{range_start}_{range_end}_v1.docx
Invoke sharepoint-filer with:
case_id: LEGAL-REPORT_{range_start}_{range_end} (synthetic case id)case_folder: Reports/Productivityfiles: the rendered .docxmemory_notes: a one-paragraph summary -- "report generated, overall load, top overdue assignees, any AT RISK lawyers". This goes into legal_copilot_memory.md so trends can be tracked across reports without re-opening the docx.The report file lands at:
myPOS Legal/Reports/Productivity/LEGAL-REPORT_{range_start}_{range_end}/LEGAL-REPORT_{range_start}_{range_end}_v1.docx
A short text summary (no markdown headers, no separator lines):
Legal team report for {range_start} -> {range_end}
Overdue: {N} tickets ({X}% of all open).
Top three slippers (by days overdue):
{key} -- {assignee} -- {days_overdue}d overdue
... up to three lines
Status:
AT RISK: {names}
OVERLOADED: {names}
OK: {everyone else}
Unassigned tickets needing routing: {N}
Filed: {sharepoint_url_of_docx}
Memory updated: {memory_file_url}
null.duedate < now() AND statusCategory != Done.npx claudepluginhub mypostech/mps-legal-legalcopilot-aiProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.