generate-status-report — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited generate-status-report (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 5 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 5 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
status report, project status, weekly update, daily standup, Jira report, project summary, blockers, progress update, Confluence report, sprint report, project update, publish to Confluence, write to Confluence, post report
Automatically query Jira for project status, analyze issues, and generate formatted status reports published to Confluence.
CRITICAL: This skill should be interactive. Always clarify scope (time period, audience, Confluence destination) with the user before or after generating the report. Do not silently skip Confluence publishing—always offer it.
Generating a status report follows these steps:
IMPORTANT: If the user's request is missing key information, ASK before proceeding with queries. Do not assume defaults without confirmation for Confluence publishing.
Clarify these details:
Project identification:
Time period:
Target audience:
Report destination:
Use the searchJiraIssuesUsingJql tool to fetch issues. Build JQL queries based on report needs.
For comprehensive queries, use the scripts/jql_builder.py utility to programmatically build JQL strings. For quick queries, reference references/jql-patterns.md for examples.
All open issues in project:
project = "PROJECT_KEY" AND status != Done ORDER BY priority DESC, updated DESCIssues updated in last week:
project = "PROJECT_KEY" AND updated >= -7d ORDER BY priority DESCHigh priority and blocked issues:
project = "PROJECT_KEY" AND (priority IN (Highest, High) OR status = Blocked) AND status != Done ORDER BY priority DESCCompleted in reporting period:
project = "PROJECT_KEY" AND status = Done AND resolved >= -7d ORDER BY resolved DESCFor most reports, execute multiple targeted queries rather than one large query:
Use maxResults: 100 for initial queries. If pagination is needed, use nextPageToken from results.
For each issue, capture:
key (e.g., "PROJ-123")summary (issue title)status (current state)priority (importance level)assignee (who's working on it)created / updated / resolved datesdescription (if needed for context on blockers)Process the retrieved issues to identify:
Metrics:
Key insights:
Categorization: Group issues logically:
Select the appropriate template based on audience. Templates are in references/report-templates.md.
Use Executive Summary Format:
Keep it concise - 1-2 pages maximum. Focus on what matters to decision-makers.
Use Detailed Technical Format:
Include more detail - Team needs issue-level visibility.
Use Daily Standup Format:
Keep it brief - This is a quick sync, not comprehensive analysis.
After generating the report, ALWAYS offer to publish to Confluence (unless user explicitly said not to).
If user hasn't specified Confluence details yet, ask:
Use the createConfluenceContent tool to publish the report.
Before authoring the body, load the authoring guidance. getContentFormatGuide is not a primary tool, so run it through execute (see Calling non-primary tools). Note that toolName takes the content key createConfluencePage, not the name of the tool you are about to call:
executeRead( # or execute(...) if your client exposes a single execute tool
name="getContentFormatGuide",
inputs={"toolName": "createConfluencePage"}
)Never skip the body because the guidance failed to load — load it first, then build a real body.
Then load the space instructions. Spaces can carry durable authoring guidance that is authoritative and overrides authoring defaults on conflict. Apply this decision rule:
getConfluenceContent call for content in the target space returnedmetadata.hasSpaceInstructions=false.
getConfluenceSpace once before authoring:executeRead( # or execute(...) if your client exposes a single execute tool
name="getConfluenceSpace",
cloudId="...",
inputs={"spaceIdOrKey": "[space ID or key]"}
)spaceInstructions. If a successful response omits them, no instructionsare configured — author with defaults and do not block.
Reuse the result for the rest of the task: do not call getConfluenceSpace again for the same space, and do not follow it with a separate getConfluenceSpaceInstructions call.
Page creation:
createConfluenceContent(
cloudId="[obtained from listConfluenceSpaces or URL]",
parent={"spaceId": "[numerical space ID]"},
contentType="page",
title="[Project Name] - Status Report - [Date]",
body={"format": "markdown", "value": "[formatted report]"}
)To nest the report under an existing page, add parentContentId to parent:
parent={"spaceId": "[numerical space ID]", "parentContentId": "[parent page ID]"},Title format examples:
Body formatting: Write the report content in Markdown and pass it as body={"format": "markdown", "value": ...}, following the spec returned by getContentFormatGuide. Use:
#, ##, ###) for structure**text**) for emphasis[PROJ-123](https://yourinstance.atlassian.net/browse/PROJ-123)Best practices:
If the user doesn't specify a Confluence space:
listConfluenceSpaces to list available spaces. This is not a primary tool, so run itthrough execute: executeRead(name="listConfluenceSpaces", cloudId="...")
If updating an existing page instead of creating new:
detail="full" returns the body (the default summary returnsonly a title, excerpt, and counts), and the doc-type response carries the snapshotToken you must pass back on the update, plus metadata.hasSpaceInstructions for step 3:
getConfluenceContent(
cloudId="...",
content_id="123456",
content_format="markdown",
detail="full",
include_metadata=True
)toolName is the content key, not the tool you call):executeRead( # or execute(...) if your client exposes a single execute tool
name="getContentFormatGuide",
inputs={"toolName": "updateConfluencePage"}
)metadata.hasSpaceInstructions=false. Reusethe result if you already loaded it for this space during this task:
executeRead( # or execute(...) if your client exposes a single execute tool
name="getConfluenceSpace",
cloudId="...",
inputs={"spaceIdOrKey": "[space ID or key]"}
)value from the step 1 response. Omitting it will fail the update:
updateConfluenceContent(
cloudId="...",
contentId="123456",
snapshotToken="[snapshotToken from the step 1 response]",
body={"format": "markdown", "value": "[updated report content]"},
versionMessage="Updated with latest status - Dec 8, 2025"
)Concurrency note: thesnapshotTokenties your edit to the version you read. Do not reuse a stale token across edits — re-read the content withgetConfluenceContentbefore each update.
User request: "Generate a status report for Project Phoenix and publish it to Confluence"
Step 1 - Identify scope:
Step 2 - Query Jira:
# Find project key first
searchJiraIssuesUsingJql(
cloudId="...",
jql='project = "PHOENIX" OR project = "PHX"',
maxResults=1
)
# Query completed issues
searchJiraIssuesUsingJql(
cloudId="...",
jql='project = "PHX" AND status = Done AND resolved >= -7d',
maxResults=50
)
# Query blocked issues
searchJiraIssuesUsingJql(
cloudId="...",
jql='project = "PHX" AND status = Blocked',
maxResults=50
)
# Query in-progress high priority
searchJiraIssuesUsingJql(
cloudId="...",
jql='project = "PHX" AND status IN ("In Progress", "In Review") AND priority IN (Highest, High)',
maxResults=50
)Step 3 - Analyze:
Step 4 - Format: Use Executive Summary Format from templates. Create concise report with metrics, highlights, and blockers.
Step 5 - Publish:
# Find appropriate space (not a primary tool - run it through execute)
executeRead(name="listConfluenceSpaces", cloudId="...")
# Load authoring guidance before composing the body
executeRead(name="getContentFormatGuide", inputs={"toolName": "createConfluencePage"})
# Load space instructions (skip only if hasSpaceInstructions was false for this space)
executeRead(name="getConfluenceSpace", cloudId="...", inputs={"spaceIdOrKey": "PHX"})
# Create page
createConfluenceContent(
cloudId="...",
parent={"spaceId": "12345"},
contentType="page",
title="Project Phoenix - Weekly Status - Dec 3, 2025",
body={"format": "markdown", "value": "[formatted markdown report]"}
)Be data-driven:
Highlight what matters:
Make it actionable:
Keep it consistent:
Provide context:
Python utility for programmatically building JQL queries. Use this when you need to construct complex or dynamic queries. Import and use the helper functions rather than manually concatenating JQL strings.
Quick reference of common JQL query patterns for status reports. Use this for standard queries or as a starting point for custom queries.
Detailed templates for different report types and audiences. Reference this to select the appropriate format and structure for your report.
The Atlassian Rovo MCP server exposes only a small set of primary tools directly in your tool list. Everything else lives in the catalog and is reached through meta-tools:
It returns the exact name and inputs to use. Do not call discover for an operation you already have as a primary tool.
expose a single `execute`, others expose `executeRead` / `executeWrite` / `executeDestructive` and expect the tier matching the operation. The arguments are identical:
executeRead( # or execute(...) if your client exposes a single execute tool
name="<operationName>",
cloudId="...",
inputs={"param": "value"}
)Rules that matter:
name and inputs — never put it insideinputs. Operations declared omitCloudId (such as getContentFormatGuide) take no cloudId.
rather than reported as an error, so a wrong name fails silently — the call succeeds and your value is simply ignored. When in doubt, read the schema or discover result first.
discover with different keywords and use thename it returns rather than guessing.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.