vlos-report — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited vlos-report (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
---
name: vlos-report
description: Generate weekly VLOS (Visual Line of Sight) executive reports from Atlassian Goals data. Use when user says "create the VLOS report", "generate VLOS report", "make the weekly VLOS", "build this week's VLOS report", or "create the weekly Product & Engineering VLOS report". This skill creates a formatted Confluence page with sections for wins, missing updates, risks, progress, and status changes for goals tagged with "mbr" and the current fiscal quarter tag.
allowed-tools: atlassian MCP tools, Bash
---
# VLOS Report Generator
Generate weekly executive VLOS (Visual Line of Sight) reports from Atlassian Goals data, formatted as Confluence pages.
## Workflow
Follow these steps in order:
### 1. Determine Report Metadata
**CRITICAL: Use `date` commands — do NOT calculate dates manually.**
Run the following Bash commands to compute the report dates:
date -v+fri "+%Y-%m-%d %b %d, %Y"
date -v-sat "+%Y-%m-%d %b %d, %Y"
date "+%m %Y"
The first two commands output `YYYY-MM-DD Mon DD, YYYY` (e.g., `2026-01-30 Jan 30, 2026`). The third outputs `MM YYYY` (e.g., `02 2026`).
Use the output directly:
- **Report date** = the Friday date from the first command
- **Comparison baseline** = the Saturday date from the second command — any goal updates before midnight on this date are considered "previous week"
- **Fiscal year and quarter tag** = from the month/year output, derive the fiscal year and quarter:
- If month >= 02 (February), FY = year + 1; otherwise FY = year
- Fiscal quarters: Q1 = Feb–Apr, Q2 = May–Jul, Q3 = Aug–Oct, Q4 = Nov–Jan
- Construct the tag in lowercase format `fy{YY}q{N}` (e.g., Feb 2026 → `fy27q1`, Jan 2027 → `fy27q4`)
- This tag is used in Step 2 to search for goals
Confluence page title format: `YYYYMMDD Product and Engineering VLOS Report`
- Example: `20260130 Product and Engineering VLOS Report`
- Note: Do not include the title in the body — Confluence adds it automatically when the page is created
### 2. Query Goals Data
Fetch all required data serially using the atlassian-goals and atlassian MCP tools.
#### Step 1: Fetch Goal List
Use atlassian-goals MCP `search_goals` to fetch goals by tag. Search for goals that have both the "mbr" tag and the fiscal quarter tag computed in Step 1:
tag LIKE "mbr" AND tag LIKE "{fiscal_quarter_tag}"
For example, if the fiscal quarter tag is `fy27q1`:tag LIKE "mbr" AND tag LIKE "fy27q1"
**Note:** Use pagination (cursor parameter) to fetch all results if there are more than the limit.
Store the list of goal IDs for the next step.
#### Step 2: Fetch Goal Details
Use atlassian-goals MCP `get_goals` (plural) to fetch all goal details in a single batch request, passing all goal IDs from Step 1.
For each goal, extract:
- Goal name
- Owner name
- Status (on track/at risk/off track/other)
- Last update date (each goal has multiple update entries, each with a timestamp — capture ALL of them; the most recent timestamp is the "last update date". If no updates exist, use the goal's creation date.)
- All update entries (including their timestamps, status changes, and content — needed for classification in Step 3)
- Sub-goals (success criteria)
- Goal KEY (e.g., 'EXPEL1-469') - NOT the UUID from the 'id' field
- Goal ID
- Web URL
**CRITICAL**: The goal 'key' field (e.g., 'EXPEL1-469') is different from the 'id' field (UUID). Always capture the KEY.
Collect ALL unique owner names from all goals.
#### Step 3: Fetch Product Launches
Use the atlassian MCP `searchJiraIssuesUsingJql` tool to find product launches.
JQL Query:project = PL AND issuetype = Epic AND status IN (Launched, Done) AND status CHANGED TO (Launched, Done) AFTER -7d ORDER BY created DESC
This finds Epics in the PL (Product Launches) project that were launched in the last 7 days.
For each launch epic, extract:
- Epic key
- Summary
- Status
- Assignee name
- URL
Collect ALL unique assignee names from all launches.
#### Step 4: Look Up AccountIds
Combine all unique owner names and assignee names into a single deduplicated list.
For EVERY unique name, use the atlassian MCP `lookupJiraAccountId` tool to get their accountId.
Build a complete mapping: `owner_name → accountId`
This mapping will be used throughout ALL sections of the report to ensure consistent user mentions.
#### Step 5: Fetch Non-MBR Goals
Use atlassian-goals MCP `search_goals` to fetch all goals tagged with `non-mbr` (without a fiscal quarter constraint, since non-MBR goals may span the full year):
tag LIKE "non-mbr"
Use pagination (cursor parameter) to fetch all results if there are more than the limit.
For each non-MBR goal, extract:
- Goal name, key, ID, and web URL
- Owner name
- Status
- Last update date (most recent update entry timestamp)
- All update entries from this week (after the comparison baseline)
- Parent goal name, key, and URL (if any)
- Sub-goals (name, key, status)
**Grouping logic:** Non-MBR goals will be grouped by their parent goal in the report. Goals with no parent are treated as top-level. If a parent goal is itself tagged `non-mbr`, do not double-count it as both a parent header and a row — show it only as the group header.
Add any new unique owner names from non-MBR goals to the accountId lookup list for Step 4 (or perform lookups now if not already done).
#### Step 6: Process and Validate Data
**Goal URL Construction:**
- Extract goal URLs from the API response
- **CRITICAL**: When constructing goal URLs, always use the goal's "key" field (e.g., "EXPEL1-462"), NOT the UUID from the goal's "id" field
- If web URLs are not available from API, construct them using:
- Organization ID (org-id)
- Site ID (site-id)
- **Goal key** (from the "key" field, e.g., "EXPEL1-462") - NOT the UUID
- Format: `https://home.atlassian.com/o/{org-id}/s/{site-id}/goal/{goal-key}`
- Example: `https://home.atlassian.com/o/9bbc0bbd-c492-47f3-9a10-640975e1a911/s/9d3fdef6-7dae-418e-837b-692c30e448ce/goal/EXPEL1-462`
- **Common mistake to avoid**: The goal "id" field uses ARI format `ari:cloud:townsquare:{cloudId}:goal/{uuid}` which contains a UUID (e.g., `9be10477-1da0-46cf-b4e8-f461dc5ca7a6`). This UUID should NEVER be used in goal URLs. Always use the "key" field instead.
**Fallback Handling:**
- If an accountId cannot be found for a user after lookup, fall back to displaying their name in plain text (this should be rare)
- If a goal URL cannot be determined, use the goal name without a link (but log a warning)
**Data Structure:**
You should now have:
- Complete goals data with keys and URLs
- Complete launches data with assignees
- Complete owner → accountId mapping
### 3. Classify Every Goal
**CRITICAL CHECKPOINT:** Before generating any report content, you MUST build a classification table for ALL goals fetched in Step 2. This table is the **sole source of truth** for determining which goals appear in which report sections.
For every goal, determine the following:
#### Last Update Date Determination
Each goal has a 1:N relationship with updates — a goal can have many update entries, each with its own timestamp.
- Examine ALL update entries for the goal
- The **last update date** = the timestamp of the most recent update entry
- If the goal has **zero** update entries, use the goal's creation date as fallback
#### Classification Columns
| Column | How to determine |
|---|---|
| **Goal name** | From API |
| **Current status** | From API (e.g., "on track", "at risk", "off track", "done") |
| **Status color** | Apply the Status Color Mapping rules below |
| **Last update date** | Most recent update entry's timestamp (see rules above) |
| **Terminal state?** | Yes if status resembles "done", "completed", or "cancelled". No otherwise. |
| **Missing update?** | Yes if last update date is BEFORE the comparison baseline (Saturday of previous week) AND goal is NOT in a terminal state. No otherwise. |
| **Completed this period?** | Yes if status is terminal (done/completed) AND an update entry AFTER the comparison baseline shows the goal transitioned to this status. No if it was already completed before the baseline. |
| **Status changed?** | Yes if update history contains a status transition AFTER the comparison baseline with BOTH previous and current status identifiable. Record "from [X] to [Y]". No if no transition found or previous status cannot be determined. |
| **Has mitigation plan?** | For at-risk/off-track goals ONLY: do the updates contain a clear WHO is doing WHAT by WHEN? Yes/No. N/A for all other goals. |
| **Report sections** | List all sections this goal belongs in (see rules below) |
#### Section Assignment Rules
Based on the columns above, assign each goal to report sections:
- **WINS**: Completed this period? = Yes
- **MISSING UPDATES**: Missing update? = Yes (this already excludes terminal states)
- **RISKS**: Current status is "at risk" or "off track" (regardless of update recency)
- **PROGRESS**: Current status is "on track" (regardless of update recency)
- **STATUS CHANGES**: Status changed? = Yes
**Goals CAN and SHOULD appear in multiple sections** when they meet multiple criteria. The criteria are independent. For example:
- A goal with "at risk" status AND no recent update → both MISSING UPDATES and RISKS
- A goal that completed this period → both WINS and STATUS CHANGES
- Evaluate each section's criteria independently — do not exclude a goal from one section because it appears in another
#### Using the Table
Once the classification table is complete:
- Every goal marked for a section **MUST** appear in that section
- No goal NOT marked for a section should appear in that section
- If you notice a contradiction while generating report content, the **table is correct** — fix the content, not the table
### 4. Generate Report Sections
Create the report body in Markdown format.
**IMPORTANT FORMATTING REQUIREMENTS:**
1. **Goal Links**: Format as `[Goal Name](url)` using the goal's key field (e.g., EXPEL1-462) in the URL — never the UUID.
- URL format: `https://home.atlassian.com/o/{org-id}/s/{site-id}/goal/{goal-key}/about`
- Example: `[C.5: Deliver committed integrations on time](https://home.atlassian.com/o/9bbc0bbd-c492-47f3-9a10-640975e1a911/s/9d3fdef6-7dae-418e-837b-692c30e448ce/goal/EXPEL1-462/about)`
2. **Owner Names**: Use plain text owner names (accountId user mentions are not supported in markdown mode).
3. **Status**: Use plain text or emoji indicators (e.g., ✅ on track, ⚠️ at risk, 🔴 off track, ⏸ pending).
4. **Section headers**: Use `##` for main sections, `###` for goal subsections.
5. **Tables**: Use standard Markdown table syntax.
#### SECTION 1: 🏆 WINS
List goals, milestones, or sub-goals that moved from incomplete to complete since the previous week. Highlight product launches prominently.
**Goal WIN qualification criteria:**
Only include goals from the classification table where "Completed this period?" = Yes. A goal qualifies ONLY if:
1. Its current status is "done" or "completed" (or similar terminal completion status)
2. Its update history contains an entry AFTER the comparison baseline showing it transitioned to this completed status
3. Do NOT include goals that were already completed before the comparison baseline
**Product/Service Launches subsection:**
- Include ALL Jira epics from the PL project that moved to Launched or Done status in the last 7 days
- Format each launch as: **[Epic Key](url) - Epic Summary**: Brief description. Owner: Name
- Link the epic key to the Jira issue URL: `https://expel-io.atlassian.net/browse/{epic-key}`
- Place this subsection prominently, typically second after Goal Completion
- If no launches found from Jira, only show launches mentioned in goal updates
#### SECTION 2: 🤷 MISSING UPDATES
Include every goal from the classification table where "Missing update?" = Yes.
**EXCLUSION RULE:** Do NOT include goals in a terminal state (done, completed, cancelled).
Table format with columns: Goal Name | Owner | Status | Last Update Date
- Goal names must be linked to Atlassian Goals
- Last update date = date only (no timestamp)
#### SECTION 3: ⚠️ RISKS
One subsection per goal from the classification table where current status is "at risk" or "off track".
- Goal name as subsection header (linked to Atlassian Goals)
- Owner name and status indicator
- What we know about the risk/issue
- **WHO is doing WHAT by WHEN** — if no clear mitigation plan exists, denote with ❌ and explicitly call out that a mitigation plan with specific owners, actions, and dates is needed.
#### SECTION 4: ⌛ PROGRESS
One subsection per goal with "on track" status:
- Goal name as subsection header (linked to Atlassian Goals)
- Owner name and status indicator
- High-level summary of progress (executive-appropriate)
- **Success criteria actuals**: For each sub-goal, show current metrics/completion status
#### SECTION 5: 🚦 STATUS CHANGES
Include only goals from the classification table where "Status changed?" = Yes.
Table format with columns: Goal Name | Owner | Previous Status | Current Status
**Status change detection criteria:**
A goal qualifies ONLY if:
1. Its update history contains a status transition AFTER the comparison baseline
2. You can definitively identify BOTH the previous status AND the current status from the update data
3. If you cannot determine the previous status with confidence, do NOT include the goal
#### SECTION 6: 📋 NON-MBR UPDATES
This section presents weekly updates for goals tagged `non-mbr`, grouped by their parent goal. It contains its own Wins and Risks subsections, followed by one group per parent.
**6a. 🏆 Non-MBR Wins:**
- List any non-MBR goals where status moved to "done" or "completed" AFTER the comparison baseline
- Format: bulleted list with linked goal name, owner, completion date, and parent group context
- If no completions, omit this subsection entirely
**6b. ⚠️ Non-MBR Risks:**
- One entry per non-MBR goal with "at risk" or "off track" status (regardless of update recency)
- Format: bold linked goal name, owner, status, what we know, and mitigation plan assessment (use ❌ if no WHO/WHAT/WHEN is documented)
- If no risks exist, omit this subsection entirely
**6c. One section per parent group:**
- Section header: parent goal name (linked) + owner + status
- Content: a table with columns: Sub-Goal | Owner | Status | This Week's Update
- "This Week's Update" = the most recent update entry's content (summarized to 1–2 sentences). If no updates this period, write "No updates this week."
- Goals with no parent get their own single-entry table under a section titled with their own name
- Goal names must be hyperlinked
**Ordering of groups:** Sort parent groups alphabetically by parent goal name. Within each group, list sub-goals with active updates first, then pending/no-update goals.
**Coverage note:** All non-MBR goals fetched — including those with no updates — MUST appear in the appropriate group table.
### 5. Create Confluence Page
Generate the report body in Markdown and **create the page directly in Confluence** using the `createConfluencePage` Atlassian MCP tool.
- **Cloud ID:** `9d3fdef6-7dae-418e-837b-692c30e448ce`
- **Space ID:** `5422710918`
- **Parent page ID:** `5445681153`
- **Title format:** `YYYYMMDD Product and Engineering VLOS Report` (e.g. `20260227 Product and Engineering VLOS Report`)
- **Content format:** Use `contentFormat: "markdown"`. Write the body in Markdown (headers, bullet lists, bold, tables, hyperlinks). Do NOT use Confluence XML storage format or ADF JSON — the API only accepts markdown for this integration.
- Do NOT include the page title inside the body — Confluence adds it automatically.
- After creating the page, return the page URL to the user so they can review it directly.
## Status Color Mapping
- **Green / ✅**: Status resembles "on track", "on target", "healthy", "green", "done", "completed"
- **Yellow / ⚠️**: Status resembles "at risk", "caution", "yellow", "needs attention"
- **Red / 🔴**: Status resembles "off track", "blocked", "red", "critical"
- **Grey / ⏸**: Status resembles "cancelled", "pending", "not started", or any other status not listed above~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.