Skip to content

Commit e2953c2

Browse files
mydeaclaude
andauthored
chore(skills): Add linear-project-status skill (#21214)
## Summary Adds a new agent skill, `linear-project-status`, that audits a Linear project's health and produces a Green/Yellow/Red status summary aimed at a project lead or engineering manager. Designed to be run roughly weekly. The skill checks: - Status-update cadence - Project lead presence (binary) and lead engagement (whether the lead is actually doing the work) - Target date presence, realism vs. open scope, and stability (push-out history per status updates) - Per-issue staleness and a project-level recent-activity pulse (last 7 days) - Milestone health - Scope stability (issue additions) - External blockers surfaced from status updates and comments Triggered via `/linear-project-status <linear-project-url-or-id-or-slug>`. ## Example Example report for `/linear-project-status https://linear.app/getsentry/project/js-migrate-senddefaultpii-to-new-datacollection-spec-560a172dc579/overview`: # Project status: [JS]: Migrate `sendDefaultPii` to new `DataCollection` spec **Verdict:** 🟒 Green β€” On track. Strong velocity (9 of 26 issues done, 5 in flight just one week into execution), Foundation milestone hit on time, fresh "onTrack" update posted today, and the lead/implementer split (Sigrid coordinates, Charly executes) is working. Watch the Migration milestone's tight Jun 8 deadline. **Project:** [\[JS\]: Migrate `sendDefaultPii` to new `DataCollection` spec](https://linear.app/getsentry/project/js-migrate-senddefaultpii-to-new-datacollection-spec-560a172dc579) Β· **Lead:** Sigrid Huemer Β· **Target:** 2026-06-12 (15 days away) Β· **Issues:** 17/26 open (9 done; 5 in flight, 12 in backlog) ## Top concerns - **Migration milestone (Jun 8, 11 days away) is the critical path.** Currently at 13% with 5 issues in flight (cloudflare, node-core, nextjs, browser, core) and several still in backlog (Node AI, core AI, remix, bun/deno, nitro/nuxt/sveltekit/astro/vercel-edge). Cleanup & Tests (Jun 10) and Docs (Jun 11) both at 0% are gated on this. If Migration slips, the project's Jun 12 target slips with it. - **Latest status update already telegraphs a 1-week milestone slip.** Sigrid's update today says the Migration milestone was moved a week because of conference attendance + illness. That's an honest acknowledgement but it's eaten the project's buffer β€” there's no slack left between Migration finishing and the project target. - **Two issues are explicitly v11 (out of scope for this Jun 12 target):** JS-2580 ("httpclient: Use granular dataCollection settings instead of sendDefaultPii gate") and JS-2509 ("Deprecate `sendDefaultPii`, resolve remaining TODOs") are tagged for the next major. They count against the open-issue total but shouldn't gate the project's Jun 12 ship β€” consider moving them to a follow-up project to clean up the count. - **Lead is engaged in coordination, not execution.** Sigrid is the lead but only assigned to 2 of 26 issues (1 done bridge issue, 1 backlog parent). Charly is doing the vast majority of the work. That's a legitimate two-person pattern, but worth being explicit about it β€” if it's a deliberate split, document it; if it's drift, rebalance. - **The big backlog of integration migrations (remix, bun/deno, nitro/nuxt/sveltekit/astro/vercel-edge, Node AI, core AI) hasn't been started yet.** Five issues in flight already; another five integration migrations are still Backlog. With 11 days to the Migration milestone, the queue needs to start clearing this week. ## Dimension breakdown | Dimension | Verdict | Notes | | ---------------- | ------- | -------------------------------------------------------------------------------------------------------------- | | Status updates | 🟒 | First update posted today (2026-05-28), health "onTrack". Project only formally started 7 days ago. | | Lead | 🟒 | Sigrid Huemer is set. | | Lead engagement | 🟑 | Sigrid assigned to 2 of 26 issues. Plays coordination/lead role; Charly does most implementation. Valid pattern but worth making explicit. | | Target date | 🟑 | 2026-06-12, 15 days away. 17/26 (65%) open. Tight but lead self-reports onTrack; Foundation hit on time. | | Target stability | 🟒 | Project target unchanged. (1 internal milestone moved a week per today's update, but project target intact.) | | Issue staleness | 🟒 | All 5 started issues updated within 6–7 days. Backlogs mostly created 13 days ago; only JS-2061 is 23d stale. | | Recent activity | 🟒 | 5 completions in last 7 days (Supabase, tRPC, logs, metrics, request data) + 5 in flight. Strong cadence. | | Milestones | 🟒 | Foundation hit on time (May 20, 100%). Migration (Jun 8), Cleanup (Jun 10), Docs (Jun 11) future. Breaking Changes is intentionally v11. | | Scope stability | 🟒 | 1 new issue (JS-2580) added since start, and that's a v11 follow-up. Scope is locked. | ## Recommended next steps 1. **Prioritize the next 3–5 Migration milestone issues** that should start this week to clear the integration backlog: pick the smallest first (e.g., JS-2507 bun/deno, JS-2508 nitro/nuxt/sveltekit/astro/vercel-edge) to keep momentum visible. 2. **Move JS-2580 and JS-2509 out of this project** (or at least off the Migration milestone) β€” both are explicitly v11. They inflate the open-issue count for a Jun 12-targeted project. 3. **Lock in a weekly cadence now that the project is in execution.** Today's update is excellent; a Mon/Tue update next week is what tells stakeholders whether Migration is on its new (slipped) Jun 8 target. 4. **Decide on the lead/implementer split explicitly.** If Sigrid leads and Charly implements by design, write that into the project description so it's not read as "lead is absent." If both are meant to implement, rebalance the next batch of assignments. 5. **Start Cleanup & Tests + Docs scoping in parallel** with the last Migration items. With Jun 10/11 deadlines, those milestones can't wait until Jun 8 β€” pull one Docs ticket (e.g., JS-2511 user docs) forward this week. --- _Data as of 2026-05-28. Run weekly to track trend._ --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8ed224c commit e2953c2

1 file changed

Lines changed: 243 additions & 0 deletions

File tree

  • .agents/skills/linear-project-status
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
---
2+
name: linear-project-status
3+
description: Analyze a Linear project's health and produce a status summary for a project lead or manager. Inspects status-update cadence, lead/owner presence, target-date realism and stability, issue staleness, milestone health, and scope creep. Use whenever the user wants a status report, project review, health check, weekly review, or audit of a Linear project β€” including phrases like "how is project X going", "give me a status on this Linear project", "audit this project", "is this project on track", "check project health", or when they paste a Linear project URL and ask for a summary. Use it even when the user doesn't explicitly say "audit" or "status" β€” if the request is fundamentally "tell me how this Linear project is doing", trigger this skill.
4+
argument-hint: <linear-project-url-or-id-or-slug>
5+
---
6+
7+
# Linear Project Status Audit
8+
9+
You are producing a project-health audit for a Linear project. The audience is a project lead or engineering manager who wants both a fast "is this on track?" verdict and a concrete list of process gaps to fix. The skill is designed to be run roughly weekly.
10+
11+
## Input
12+
13+
The user will provide one of:
14+
15+
- A Linear project URL (e.g., `https://linear.app/<workspace>/project/my-project-abc123/overview`)
16+
- A project slug (e.g., `my-project-abc123`)
17+
- A project name or ID
18+
19+
Pass whatever they gave you straight to `get_project`'s `query` parameter β€” Linear's MCP accepts all three forms. Do not try to parse the URL yourself.
20+
21+
## Data to collect
22+
23+
### Step 1 β€” Resolve the project UUID first
24+
25+
Linear's MCP has a quirk where `list_issues` and related calls sometimes silently return an empty list when given a slug or name, even though issues exist. To avoid this, always resolve the project to its UUID before doing anything else:
26+
27+
1. Call `mcp__claude_ai_Linear__get_project` once with whatever the user provided (URL, slug, name, or ID) as `query`, plus `includeMembers: true, includeMilestones: true, includeResources: true`.
28+
2. Extract the `id` field from the response β€” this is the project UUID, e.g. `4cd9abe3-834e-43e4-926e-630e30044c0a`.
29+
3. Use that UUID β€” never the slug β€” for every subsequent call in Step 2.
30+
31+
If `get_project` returns no result or an error, stop and tell the user β€” don't fabricate.
32+
33+
### Step 2 β€” Fetch the rest of the data in parallel using the UUID
34+
35+
Pass the UUID from Step 1 as the `project` / `projectId` argument to each of these:
36+
37+
1. `mcp__claude_ai_Linear__get_status_updates` with `type: "project", project: <uuid>, limit: 20, orderBy: "createdAt"` β€” recent status updates, newest first. **Read the bodies.** They often describe target-date changes, scope changes, or blockers that don't show up anywhere else.
38+
2. `mcp__claude_ai_Linear__list_issues` with `project: <uuid>, limit: 250, includeArchived: true` β€” all current issues. Use `includeArchived: true` (the MCP sometimes filters out non-archived issues otherwise; filter them yourself in analysis if needed). If `hasNextPage` is true, paginate via `cursor` until you have them all (cap at ~1000 to stay reasonable).
39+
3. `mcp__claude_ai_Linear__list_issues` with `project: <uuid>, limit: 100, createdAt: -P30D, orderBy: "createdAt", includeArchived: true` β€” issues added in the last 30 days, for scope-creep analysis.
40+
4. `mcp__claude_ai_Linear__list_issues` with `project: <uuid>, limit: 100, updatedAt: -P7D, orderBy: "updatedAt", includeArchived: true` β€” issues that moved this week, for the recent-activity pulse check.
41+
5. `mcp__claude_ai_Linear__list_comments` with `projectId: <uuid>, limit: 30` β€” recent project-level discussion. Useful for catching live blockers and decisions not yet reflected in updates.
42+
43+
If any call errors, stop and tell the user β€” don't fabricate.
44+
45+
### Handling large issue lists
46+
47+
For projects with many issues (50+), `list_issues` can return a response too large to fit in a single tool result. If you get a "result exceeds maximum allowed tokens" error pointing to a saved file, use `jq` (via the Bash tool) on that file to aggregate what you need β€” counts by state, completions in the last 7/30 days, assignees, etc. β€” rather than trying to read the file line by line. Example: `jq '.issues | group_by(.status) | map({state: .[0].status, count: length}) | .[]' <file>`.
48+
49+
## Analysis dimensions
50+
51+
For each dimension below, derive a verdict (`ok` / `warn` / `bad`) and a one-sentence rationale. Apply the default thresholds but use judgment when the context clearly justifies an override (and say so in the rationale). All "days since" calculations should be relative to today.
52+
53+
### 1. Status update cadence
54+
55+
Goal: project should have weekly updates so stakeholders aren't in the dark.
56+
57+
| Days since last update | Verdict |
58+
| ---------------------- | ------- |
59+
| ≀ 8 days | ok |
60+
| 9–14 days | warn |
61+
| > 14 days, or none | bad |
62+
63+
Don't flag single-author updates. Projects are typically owned by one person and it's fine β€” even expected β€” for that person to write all updates. The cadence is what matters, not the authorship distribution.
64+
65+
### 2. Project lead
66+
67+
This dimension is binary β€” either there's a lead on the project or there isn't:
68+
69+
| Condition | Verdict |
70+
| ---------------------------- | ------- |
71+
| `lead` is set on the project | ok |
72+
| No lead set | bad |
73+
74+
Every project must have a designated lead. Don't try to infer a "de facto lead" from update authorship β€” the field is either set or it isn't. A missing lead is one of the most common process gaps; flag it visibly.
75+
76+
### 2b. Lead engagement
77+
78+
Separately from the binary "is there a lead" check, evaluate whether the lead is actually doing project work. Surface this as its own line item in the report (e.g., "Lead engagement: warn").
79+
80+
| Condition | Verdict |
81+
| ------------------------------------------------------------------------ | ------- |
82+
| Lead is assigned to a meaningful share of the project's issues | ok |
83+
| Lead is assigned to none or only a tiny fraction of the project's issues | warn |
84+
| No lead is set (covered by dimension 2; skip this dimension) | n/a |
85+
86+
Why: leads should be doing the work, not just owning the project nominally. One person doing the majority of issues is fine β€” that's how single-owner projects naturally look. The thing to flag is the lead being absent from the work, not other contributors being light.
87+
88+
### 3. Target date β€” presence and realism
89+
90+
First, check presence β€” a target date is required on every project:
91+
92+
- No target date β†’ `bad`. An end-state without a date is a backlog, not a project. Always flag this as a top concern.
93+
- Target date set β†’ judge realism (below).
94+
95+
To judge realism, compare days remaining to the open scope. Rough heuristic:
96+
97+
- `bad` if target date is within 14 days AND (there are open issues with no recent activity, OR open issues outnumber completed ones). Both sub-conditions are scoped to the 14-day window β€” a young project with mostly-open issues isn't `bad`, only one about to ship that isn't ready.
98+
- `warn` if target date is within 30 days AND >40% of issues are still open, OR the target date is already in the past while the project is not completed.
99+
- `ok` otherwise.
100+
101+
These are anchors, not rules β€” if status updates say "we're descoping X" or "ship date moved deliberately", weight that.
102+
103+
### 4. Target date stability
104+
105+
A project's target date should change rarely. Each push-out is a small admission that the plan wasn't trusted.
106+
107+
You typically can't query the target-date history directly. Read the status updates and the project description for explicit mentions of date changes. Count distinct dates that have been referenced as "the target".
108+
109+
| Pushes mentioned in recent updates | Verdict |
110+
| ---------------------------------- | ------- |
111+
| 0–1 | ok |
112+
| 2 | warn |
113+
| 3+ | bad |
114+
115+
If you can't tell, say so β€” don't guess. State: "Could not determine target-date history from available data."
116+
117+
### 5. Issue staleness
118+
119+
For each open issue (states: backlog, unstarted, started), compute days since `updatedAt`.
120+
121+
- `bad`: an issue is `started` (In Progress) but hasn't been touched in > 14 days. In-progress work should be finishing, not sitting.
122+
- `warn`: > 30% of open issues haven't been touched in > 21 days.
123+
- `ok`: most open issues moved within the last few weeks.
124+
125+
Backlog-state issues that are stale are less alarming than started-state ones β€” call them out separately if it matters.
126+
127+
### 6. Milestone health
128+
129+
For each milestone, check the target date and the state of its associated issues. (You may need to look at each issue's milestone via the issue payload; otherwise infer from titles/labels.)
130+
131+
- `bad`: milestone target date in the past AND issues attached are not all completed.
132+
- `warn`: milestone target date in the past AND it's unclear whether the work shipped; OR milestone has no issues attached at all (it's just a date on a calendar).
133+
- `ok`: milestones are in the future, or past ones are clearly done.
134+
135+
A project with no milestones isn't automatically a problem on small projects β€” but on multi-month projects, the absence of milestones is itself a `warn`.
136+
137+
### 7. Scope stability (issue additions)
138+
139+
Compare issues added in the last 30 days against total open issues, and look at whether new issues are still being added late in the project's life.
140+
141+
- `bad`: target date is < 30 days away AND new issues are still being added at a non-trivial rate.
142+
- `warn`: > 30% of currently-open issues were created in the last 30 days on a project that's been going for months.
143+
- `ok`: rate of new issues is decreasing, or matches expected discovery on a young project.
144+
145+
The point of this check: a project should converge toward a defined end state. A project where issues keep getting added is really a workstream, not a project.
146+
147+
### 8. Recent activity (last 7 days)
148+
149+
Per-issue staleness (dimension 5) tells you whether individual tickets are sitting. This dimension is the project-level pulse: did _anything_ happen this week?
150+
151+
Count issues that were either **completed** or **updated while in a `started` state** in the last 7 days. (Use the `list_issues` `updatedAt: -P7D` filter, or filter the issues you already fetched.)
152+
153+
| Activity in last 7 days | Verdict |
154+
| -------------------------------------------------------------------- | ------- |
155+
| Several issues moved or completed; matches the project's normal pace | ok |
156+
| 1–2 issues moved; below the project's normal pace | warn |
157+
| Zero issues moved or completed | bad |
158+
159+
Why this matters even when other dimensions are fine: a project where no work happens for a week β€” even one with weekly status updates and a present lead β€” usually means the lead is working on something else, or real work is happening in PRs/Notion/Slack that isn't reflected in Linear. Both are worth surfacing.
160+
161+
Calibrate to the project's normal cadence (read recent history): a research project might genuinely move slowly and that's fine; a delivery project with no movement in a week is a `bad` even if the target date is months away.
162+
163+
### Blockers
164+
165+
Read the latest 2–3 status updates and the most recent project-level comments for any of:
166+
167+
- External upstream dependencies (e.g., "waiting on upstream Bun PR", "blocked on platform team")
168+
- Unresolved technical decisions ("we still need to pick X over Y")
169+
- People-blockers ("need review from N", "waiting on access")
170+
171+
If you find any, surface them as their own item in **Top concerns** β€” labeled "Blocker: ..." β€” and include a one-line description of what's blocking and what would unblock it. Blockers are different from staleness: a project can be perfectly healthy in cadence and still be blocked. Naming them explicitly is often the single most useful thing the report does.
172+
173+
If status updates and comments don't mention any blockers, simply omit the blocker line β€” don't fabricate one.
174+
175+
## Computing the overall verdict
176+
177+
Roll the per-dimension verdicts into one of:
178+
179+
- **🟒 Green β€” On track.** All ok, or at most one `warn` that's clearly minor.
180+
- **🟑 Yellow β€” Needs attention.** Multiple `warn`s, or one `bad` that has a clear path to resolution.
181+
- **πŸ”΄ Red β€” At risk.** Two or more `bad`s, or a single `bad` that meaningfully threatens the target date (e.g., target imminent + stale issues).
182+
183+
Don't double-count: a missing target date inflates a few dimensions; weigh holistically.
184+
185+
## Output
186+
187+
Produce a single markdown report in the chat, using the structure below. Keep prose tight β€” managers skim.
188+
189+
```markdown
190+
# Project status: <Project Name>
191+
192+
**Verdict:** <emoji + Green/Yellow/Red> β€” <one-line summary>
193+
194+
**Project:** [<name>](url) Β· **Lead:** <name or "β€”"> Β· **Target:** <date or "β€”"> Β· **Issues:** <open>/<total> open
195+
196+
## Top concerns
197+
198+
<ranked bullets, most important first. Each bullet states the problem and what to do about it. Limit to ~5.>
199+
200+
- **<short headline>:** <1–2 sentence description, with concrete numbers where possible. Recommendation if not obvious.>
201+
202+
## Dimension breakdown
203+
204+
| Dimension | Verdict | Notes |
205+
| ---------------- | -------- | ----------------------------------------------------- |
206+
| Status updates | 🟒/🟑/πŸ”΄ | <e.g., "Last update 3 days ago by @alice"> |
207+
| Lead | 🟒/🟑/πŸ”΄ | <e.g., "@alice"; binary β€” set or not> |
208+
| Lead engagement | 🟒/🟑 | <e.g., "Assigned to 7/8 issues"; omit row if no lead> |
209+
| Target date | 🟒/🟑/πŸ”΄ | <e.g., "2026-06-30, 33 days away β€” looks tight"> |
210+
| Target stability | 🟒/🟑/πŸ”΄ | <e.g., "Pushed twice in last 6 weeks per updates"> |
211+
| Issue staleness | 🟒/🟑/πŸ”΄ | <e.g., "4 in-progress issues untouched > 14 days"> |
212+
| Recent activity | 🟒/🟑/πŸ”΄ | <e.g., "3 issues moved in last 7d"> |
213+
| Milestones | 🟒/🟑/πŸ”΄ | <e.g., "Milestone 'Alpha' past due, 3 issues open"> |
214+
| Scope stability | 🟒/🟑/πŸ”΄ | <e.g., "12 new issues in last 30d, target in 20d"> |
215+
216+
## Recommended next steps
217+
218+
<3–5 concrete actions for the project lead. Each should be doable this week.>
219+
220+
1. ...
221+
2. ...
222+
223+
---
224+
225+
_Data as of <ISO date>. Run weekly to track trend._
226+
```
227+
228+
Notes on the report:
229+
230+
- **Lead with the verdict.** That single line is the part a manager actually reads.
231+
- **Top concerns are the value.** A green project gets a short report. A red one gets the bullets that matter, not all seven dimensions in detail.
232+
- **Numbers beat adjectives.** "4 issues stale > 14d" beats "several stale issues". Always cite specifics.
233+
- **Don't pad.** If a dimension is fine, the row in the table is enough; don't write a paragraph for every ok.
234+
- **Don't quote issue titles unless they illustrate the point.** A list of titles isn't insight.
235+
- **Time anchoring:** all "X days ago" should be relative to today (use the system date). If the data feed is older than your run time, prefer the data's date and say so.
236+
237+
## Common failure modes to avoid
238+
239+
- **Treating Linear's defaults as health signals.** A project that has no milestones is not automatically broken; it's a `warn` only if the project is large enough to warrant them. Calibrate to the project size.
240+
- **Confusing a slow-moving project with a stuck one.** Some projects have low velocity by design (e.g., research, long-running compliance). If the status updates clearly explain low velocity, downgrade staleness flags accordingly.
241+
- **Citing issue counts without context.** "10 open issues" is meaningless without total / target-date / age. Pair every count with a denominator or a date.
242+
- **Refusing to give a verdict.** The user wants a Green/Yellow/Red call. Even if you're uncertain, pick one and explain the uncertainty in the verdict line. Don't punt.
243+
- **Hallucinating data Linear didn't return.** If the data is missing, say "could not determine from available data" rather than inventing.

0 commit comments

Comments
Β (0)