| name | projects-health-check |
| description | 🩺 PROJECTS: Health check — instant multi-source snapshot of any project's velocity, blockers, decisions, and open threads. Use whenever anyone asks about the current state, health, or status of a specific project — especially ad-hoc or before a client call. Triggers include: "jaki jest stan [projektu]", "jak idzie [projekt]", "co słychać na [projekcie]", "zrób health check [projektu]", "sprawdź co się dzieje w [projekcie]", "mam call z klientem — przypomnij mi co się dzieje", "co powinienem wiedzieć przed spotkaniem z [klientem]", "czy coś blokuje [projekt]", "what's the status of [project]", "catch me up on [project]", or any variation of a quick project situational awareness check. Also trigger proactively when a Jira project key, Slack channel name, or client name is mentioned with a follow-up implying a need for current context. Scans Fireflies, Slack, Jira, and Confluence in parallel and returns a structured snapshot. |
Project Health Check
Purpose
Give the user an instant, multi-source situational snapshot of any client project before
a call, during a status review, or when something feels off. Output is shown in chat only —
never written anywhere automatically.
This skill is generic: it works for any project. Project name/key is
supplied by the user at trigger time.
Key Constants
- Jira / Confluence Cloud ID: resolve dynamically via
getAccessibleAtlassianResources if not already known. If multiple orgs are returned, pick the one matching the project or ask the user.
- User's Slack handle / email: use the identity from your project context, or ask the user if unknown.
- Default scan window: last 14 days (covers sprint + a bit of buffer)
Step 0: Resolve the project
Early exit: If no project name, Jira key, client name, or Slack channel can be inferred from the user's message, ask before doing anything else: "Which project should I run the health check on?" Don't scan anything until this is clear.
From what the user said, extract:
- Project name (human-readable, e.g. "Acme", "ProjectX")
- Jira project key if known (e.g.
ACM, PX) — otherwise search for it
- Slack channels — search for channels matching the project name if not known
If the project is ambiguous or multiple matches are possible, ask the user to clarify before
proceeding. Don't guess.
Skill overlap note: If the user explicitly mentions an upcoming calendar meeting by name or timing (e.g. "I have a call in 30 min"), consider using meetings-prep instead — it handles calendar lookup and attendee context. Use health-check when the ask is project-level situational awareness, not meeting-specific prep.
Jira key lookup (if not known):
getVisibleJiraProjects → filter by name match
Slack channel lookup (if not known):
slack_search_channels(query="<project_name>")
Look for channels like #proj-<name>, #<name>-internal, #<name>-mgmt, etc.
Step 1: Scan all sources in parallel
Run everything below at the same time. Don't wait for one before starting another.
1a. Jira — sprint & backlog health
JQL: project = <KEY> AND updated >= -14d ORDER BY updated DESC
fields: summary, status, assignee, issuetype, priority, created, updated
maxResults: 40
Extract:
- Tickets Done in the last 14 days → velocity signal
- Tickets In Progress right now → active work
- Tickets To Do / Backlog that are overdue or stale (updated > 14 days ago, still open)
- Any tickets with no assignee (ownership gap)
- Any Epics to understand current phase
Stale ticket heuristic: issuetype = Story or Task, status not in (Done, Cancelled),
last updated more than 14 days ago → flag as potentially stale.
1b. Slack — recent activity & signals
Search across all channels related to the project:
slack_search_public_and_private(
query="<project_name> after:<scan_start_date>",
sort="timestamp",
limit=30
)
Note: Use after:YYYY-MM-DD format for the date modifier, e.g. after:2026-05-07. Other formats silently return no results.
If known channel IDs are available, also read them directly:
slack_read_channel(channel_id=<id>, oldest=<unix_ts>, limit=50)
For any message with escalation signals ("blocker", "stuck", "problem", "risk"), read the full thread to get complete context — the resolution or full backstory is almost always in the replies:
slack_read_thread(channel_id=<id>, thread_ts=<ts>)
Look specifically for:
- Escalations or frustration signals — "blocker", "stuck", "problem", "risk", "delay", "waiting",
"no response", "not received" (or equivalent in your team's language)
- Client interactions — messages to/from client, demo feedback, approval requests
- Team signals — someone leaving, someone being added, capacity concerns
- Open questions with no reply (thread with 0 responses or last message unanswered)
1c. Fireflies — recent meetings
fireflies_get_transcripts(keyword="<project_name>", fromDate=<scan_start>, limit=5)
Fallback: search by participants: ["<your-email>"], then filter manually.
For each relevant meeting: call fireflies_get_summary. Extract:
- Action items that are still open
- Decisions made (and whether they've been documented)
- Risks or blockers mentioned verbally
- Client sentiment (positive/neutral/negative tone in summary)
1d. Confluence — open decisions & documentation gaps
CQL: space = "<project_space>" AND (type = page OR type = blogpost) AND lastModified >= "<scan_start>"
ORDER BY lastModified DESC
limit: 10
If you don't know the Confluence space, search:
getConfluenceSpaces → filter by project name match
If multiple spaces match, pick the closest one or ask the user.
Look for:
- Decision Log — are there open/pending decisions? When was it last updated?
- Meeting notes — is documentation current, or are recent meetings missing notes?
- Any pages flagged as "Draft" or "TODO"
1e. Gmail — email threads related to the project
search_threads(
query="<project_name> after:<YYYY/MM/DD 14 days ago>",
maxResults: 10
)
Extract:
- Threads marked "action required" or awaiting the user's reply
- Client communications: approvals, sign-offs, complaints, escalations
- Decisions or scope changes communicated via email but not in Jira/Slack
- Any open thread where the last message is from someone else (potential unanswered ask)
If nothing actionable found: skip this source in the output silently.
Step 2: Synthesise
Cross-reference all sources. Look for:
- Consistency gaps — something decided in Fireflies/Slack but not in Jira/Confluence
- Stale threads — open Slack questions with no follow-up, unactioned Fireflies items
- Silent risks — things that haven't been discussed recently but probably should be
(e.g., a blocker mentioned 2 weeks ago with no resolution update)
Step 3: Output
Context mode — calibrate depth to situation
Before writing, determine which mode applies:
| Mode | When | Output style |
|---|
| Pre-call (5-min) | "I have a call in 30 min" | Lead with ⚠️ flags and blockers, compress the rest. Total: ~200 words. |
| Weekly review | Scheduled check-in, no urgency | Full structured output. Total: ~300–400 words. |
| Deep review | Something feels off, post-incident | Expand OPEN THREADS and ATTENTION FLAGS, name sources explicitly. Total: up to 500 words. |
Default to Weekly review if no context given.
Present in chat. Use this structure:
🩺 Health Check: <Project Name> — <DD.MM.YY>
Scan window: last 14 days | Mode: Pre-call / Weekly / Deep
📊 VELOCITY
• Done this period: X tickets | In Progress: Y | Stale/stuck: Z
• [1–2 sentence narrative — is the pace healthy? accelerating? stalling?]
✅ WHAT'S MOVING
• [Specific thing in active progress — name the feature, not just "development"]
• [Max 4 bullets — most recent / most impactful first]
• Omit this section if nothing material moved this period — don't list routine ongoing work.
🚧 BLOCKERS & RISKS
• [Blocker] — source: [Slack/Fireflies/Jira], since: [date if known]
• [Risk] — [brief context, what could go wrong]
• If nothing: "No active blockers identified in this scan window."
🔄 OPEN THREADS (need follow-up)
• [Unanswered question or unactioned item] — [where it lives, who owns it, age in human terms: "open for 3 days" / "unanswered since May 14"]
• If nothing: "No open threads identified."
📋 DECISIONS
• [Decision made this period] — [source, date]
• [Pending decision awaiting input] — [from whom, since when]
• If nothing recent: "No new decisions in scan window. Decision Log last updated: [date]."
⚠️ ATTENTION FLAGS
[Only include if something warrants immediate action. Omit section entirely if nothing qualifies.]
• [Flag] — [why it matters] → [suggested next action]
Quality checklist (run before presenting)
Output rules
What to include:
- Specific over generic. Name actual tickets, actual threads, actual decisions. Never write "development is progressing" — write what is being developed.
- Evidence-based. Every bullet traceable to a source (Jira ticket, Slack message, Fireflies summary). If you can't source it, don't include it.
What to explicitly omit:
- Don't list every Done ticket verbatim — group by theme or name only the 2–3 most significant.
- Don't include standard ongoing work that has no change or signal ("backend development continued").
- Don't populate a section with filler just to look complete. An honest "nothing to report" is better than a padded bullet.
- Don't include something as a "risk" unless it's actually unresolved. Past resolved blockers aren't risks.
Per-section length targets (weekly review mode):
- VELOCITY: 1 line of numbers + 1–2 sentence narrative
- WHAT'S MOVING: 2–4 bullets, 1 line each
- BLOCKERS & RISKS: 1–4 bullets; if more than 4, group by theme
- OPEN THREADS: 1–3 bullets (surface only actionable ones)
- DECISIONS: 2–4 bullets
- ATTENTION FLAGS: 1–3 bullets maximum — if you have more, the project needs a call, not a health check
Language: match the language the PM writes in.
Customization points
When adapting this skill for a specific project (or another PM), update these fields:
| Field | Default | Override |
|---|
SCAN_WINDOW_DAYS | 14 | e.g. 7 for fast-moving sprints |
JIRA_KEY | resolved dynamically | hardcode for frequent projects |
SLACK_CHANNEL_IDS | resolved dynamically | hardcode known channels |
CONFLUENCE_SPACE | resolved dynamically | hardcode if known |
STALE_THRESHOLD_DAYS | 14 | adjust per team cadence |
For recurring projects, consider adding a ## Known Projects section below with
pre-resolved constants (Jira key, Slack channel IDs, Confluence space) to skip the lookup steps and improve reliability.
After presenting
Ask: "Anything specific you want me to dig into further?"
Then propose 2–4 grounded follow-up actions based on what was actually found — don't suggest generic actions that don't connect to the scan results. Examples of grounded follow-ups:
- If stale tickets were found → "Show me the full list of stale tickets with summaries?"
- If an unresolved Fireflies action item surfaced → "Pull the full transcript from that meeting?"
- If a Slack question had no reply → "Draft a follow-up message to [person] about [topic]?"
- If a decision was mentioned verbally but not in Jira → "Check if this decision is tracked anywhere in Jira?"
- If action items were found → "Create Jira tickets from these action items?" (hand off to
jira-create-ticket if available)
Never suggest an action that has no basis in what was found.