# Flow Analysis

> >

- **Type:** Skill
- **Install:** `agentstack add skill-dotnet-arcade-skills-flow-analysis`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [dotnet](https://agentstack.voostack.com/s/dotnet)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [dotnet](https://github.com/dotnet)
- **Source:** https://github.com/dotnet/arcade-skills/tree/main/plugins/dotnet-dnceng/skills/flow-analysis

## Install

```sh
agentstack add skill-dotnet-arcade-skills-flow-analysis
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Flow Analysis

Analyze VMR codeflow PR health using **scripts** for data collection and **MCP tools** for enrichment and remediation. For single-PR analysis, `Get-CodeflowStatus.ps1` does comprehensive data collection (VMR commit comparison, forward flow discovery, staleness detection); maestro MCP tools provide subscription triggering and build freshness. For repo-wide flow health, `flow-health.cs` handles batch GitHub scanning in parallel.

> 🚨 **NEVER** use `gh pr review --approve` or `--request-changes`. Only `--comment` is allowed.

## When to Use This Skill

Use this skill when:
- A codeflow PR (from `dotnet-maestro[bot]`) is stale or failing and you need to understand why
- You need to check if a specific fix has flowed through the VMR pipeline
- A PR has a Maestro staleness warning or conflict
- You want to check overall flow health for a repo ("what's the flow status for the sdk?")
- You need to diagnose why backflow PRs are missing or blocked
- You're asked "is this codeflow PR up to date", "why is the codeflow blocked", "what's the flow status for net11"

## Prerequisites

- **Maestro MCP server** — provides subscription health, build freshness, and codeflow management. See [lewing/maestro.mcp](https://github.com/lewing/maestro.mcp) for setup.
- **GitHub CLI (`gh`)** — must be installed and authenticated. Required by `flow-health.cs`.

## Quick Start

For **"is the backflow healthy for repo X on branch Y?"** — use PR Analysis (`Get-CodeflowStatus.ps1 -Repository -Branch`). The script finds the open backflow PR (if any), compares VMR commits, discovers forward flow, and extracts warnings — all in one call.

For **"what's the flow status across all repos?"** or **multi-repo/multi-branch scanning** — use the Codeflow Overview (MCP tools for subscription health + build freshness across many repos simultaneously).

For **investigating a specific PR** — use PR Analysis (`Get-CodeflowStatus.ps1 -PRNumber`). If **no open PR exists**, the script reports this; use MCP tools to check the subscription state.

## Codeflow Concepts

- **Backflow** (VMR → product repo): PRs titled `[branch] Source code updates from dotnet/dotnet`
- **Forward flow** (product repo → VMR): PRs titled `[branch] Source code updates from dotnet/`
- **Staleness**: Forward flow merging while backflow PR is open blocks further updates. **Merging `main` into the PR branch does NOT resolve staleness** — it only fixes git conflicts. The only resolutions are: merge the PR as-is, close it, or force trigger the subscription.
- **VMR backflow vs dependency subs**: Don't confuse stuck dependency subscriptions (from product repos) with VMR backflow problems (from `dotnet/dotnet`). See [vmr-codeflow-reference.md](references/vmr-codeflow-reference.md#vmr-backflow-vs-dependency-subscriptions) for details.

## Channel Resolution

Users refer to channels with shorthand. **.NET major = year − 2015** (2026 → .NET 11, 2025 → .NET 10).

| User says | Resolve to | Example exact channel name |
|-----------|-----------|---------------------------|
| `net11` | Filter channels for `11.0` | `.NET 11.0.1xx SDK` |
| `11.0.1xx` | Use directly | `.NET 11.0.1xx SDK` |
| `net10 3xx` | Version 10, band 3 | `.NET 10.0.3xx SDK` |
| `release/10.0.3xx` | Strip `release/` → `10.0.3xx` | `.NET 10.0.3xx SDK` |
| `main` | Current dev (major = year − 2015, band = `1xx`) | `.NET 11.0.1xx SDK` |

> ⚠️ **Channel filter requires an exact substring match.** Use the full channel name (e.g., `.NET 11.0.1xx SDK`) when filtering codeflow PRs or subscriptions. Partial names like `.NET 11.0` may not match.

### SDK Bands and Forward Flow

The **1xx band** has full source-build with runtime forward flow. **2xx/3xx bands** consume runtime as prebuilts — missing runtime forward flow on these bands is expected, not broken. See [vmr-codeflow-reference.md](references/vmr-codeflow-reference.md#sdk-bands-and-forward-flow) for the full band table.

## Analysis Modes

| Question | Mode | Approach |
|----------|------|----------|
| "What's the flow status for X?" | **Codeflow overview** | Codeflow statuses → subscription health with validate → build freshness |
| "Is backflow healthy for X on Y?" | **PR analysis** | `Get-CodeflowStatus.ps1 -Repository -Branch` → read output → MCP enrichment |
| "Why is this PR stale/blocked?" | **PR analysis** | `Get-CodeflowStatus.ps1 -PrUrl` → read output → MCP enrichment |
| "What's the flow status across all repos?" | **Codeflow overview** | Codeflow statuses for each repo → subscription health + build freshness |
| "Full flow health report for X" | **Flow health** | `flow-health.cs` script for batch GitHub scanning + maestro enrichment |

## Codeflow Overview Workflow

When the user asks "what codeflow PRs are active?" or "what's the flow status?", start with **codeflow statuses** for the target repo/branch — one call shows per-mapping forward flow and backflow status with active PRs and build staleness. Then drill into problems with subscription health and scripts.

> 🚨 **Trust "commits behind", don't trust "builds behind".** Subscription health returns two kinds of staleness numbers — **"N commits behind"** is real commit distance (trust it, report it directly) and **"~N builds behind"** (note the `~` prefix) is a meaningless BAR build ID delta that overstates staleness by 10x-300x. For any stale entry showing `~builds behind`, compute the real commit distance yourself (see Step 5).

### Step 0: Quick Status via Codeflow Statuses

For any repo or the VMR, get **codeflow statuses** for the repo and branch (defaults to `dotnet/dotnet` on `main`). This returns per-mapping forward flow and backflow status in one call — active PRs, build staleness, and subscription details. Use this as the initial triage to identify which mappings need investigation before drilling into subscription health.

> 💡 **When to skip Step 0**: If you already have a specific PR URL or subscription ID, go directly to PR Analysis or subscription health. Codeflow statuses is for "what's the overall picture?" questions.

### Step 1: Check Subscription Health

Check subscription health for the target repository. This shows which subscriptions are stale and which are current. Entries showing "N commits behind" (no `~`) have real commit distances — use those directly. Entries showing "~N builds behind" (with `~`) need commit distance computation in Step 5.

Use the `validate` option to enable **cross-validation** — this checks subscription state against GitHub PR state, detects state oscillation patterns, and traces source-manifest commits. Always use `validate` when investigating stuck subscriptions.

> ⚠️ **Output includes ALL subscriptions** (all branches and channels). For a version-specific query like "net11 status", filter the results for channels containing your target version (e.g., `11.0`) and the relevant branch (`main` for current dev).

### Step 2: Check Forward Flow

**Before drilling into backflow problems**, check for open forward flow PRs from the product repo into `dotnet/dotnet`. An open forward flow PR is the #1 cause of backflow staleness — if forward flow is pending, backflow is blocked by design.

If codeflow statuses (Step 0) shows a forward flow subscription with failures or high commit distance, investigate:

1. **Check the subscription's update history** — look for consecutive `Failed` or state oscillation (e.g., repeating `ApplyingUpdates → MergingPullRequest → ApplyingUpdates`). State oscillation means Maestro keeps retrying but something prevents completion.
2. **Check if a tracked PR exists** — a forward flow subscription may report failures but actually have a merged-then-reopened PR, or no PR at all. The tracked PR tells you what Maestro thinks is happening.
3. **Cross-validate against GitHub** — if Maestro says the subscription is failing but a PR exists and is merged, the subscription has a **bookkeeping bug** (Maestro never updated `LastAppliedBuildId`). Use `validate` on subscription health to detect this automatically.

> 🚨 **Forward flow bookkeeping bug**: When a forward flow subscription shows "N builds behind" with consecutive failures but GitHub shows PRs merging successfully, this is a known Maestro issue where `LastAppliedBuildId` doesn't update after merge. The subscription is stuck in an infinite retry loop. **Remedy**: force-trigger the subscription — this resets Maestro's state by creating a fresh PR branch.

### Step 3: List Tracked PRs

List all codeflow PRs currently tracked by Maestro, optionally filtering by channel name.

> ⚠️ **Output is large** (200+ PRs across all repos). Filter by `channelName` parameter (use exact name like `.NET 11.0.1xx SDK`), or grep/search the output for your target repo.

### Step 4: Drill Into Problems

For subscriptions that are stale — whether they have a stuck PR or no PR at all:
- Check the subscription's update history to find the failure point
- Check build freshness to rule out VMR build failures (if builds are stale, it's a VMR issue, not Maestro)
- For stuck PRs, check the PR's age and recent activity — a PR open >3 days with no progress needs attention

### Step 5: Get Real Commit Distance

For stale entries showing "~N builds behind", request **commit details** when checking subscription health. This returns the actual commit count and recent commit metadata (SHA, message, author, date) — no manual GitHub API calls needed.

Report the commit count as "N commits behind". Use the recent commit list to explain *what* is behind (e.g., "3 commits behind — latest: Fix NuGet restore race condition").

### Step 6: Enrich with GitHub Data

Use GitHub PR details to check state, comments, and merge status for any PRs flagged as problematic.

### Multi-Repo Health Check

When asked about flow health across "all repos" or a major version (e.g., "net11 status"), check the core product repos. Subscription health calls are independent — run them in parallel.

**Core repos**: `dotnet/runtime`, `dotnet/sdk`, `dotnet/aspnetcore`, `dotnet/roslyn`, `dotnet/efcore`, `dotnet/winforms`, `dotnet/wpf`, `dotnet/msbuild`

**Branch names differ across repos** — `runtime`/`aspnetcore` use `release/X.0`, `sdk` uses `release/X.0.Nxx`, `msbuild` uses `vsNN.N`, `roslyn` uses `release/devNN.0` (VS major = .NET major + 8). Current dev is `main` for all. See [vmr-codeflow-reference.md](references/vmr-codeflow-reference.md#branch-naming-per-repo) for the full table.

When asked about a major version, check **all branches** — don't ask for clarification. Present a consolidated cross-repo summary.

## PR Analysis Workflow

> 🚨 **Script-first.** Always run `Get-CodeflowStatus.ps1` first. It produces a `[CODEFLOW_SUMMARY]` JSON block with VMR commit comparison, forward flow discovery, and staleness detection that cannot be replicated by individual MCP calls. **Do NOT re-query the same data via MCP tools** — read and interpret the script output.

### Step 1: Run the Script

```powershell
# Analyze a specific PR by number
./scripts/Get-CodeflowStatus.ps1 -Repository "dotnet/runtime" -PRNumber 12345

# Check if a PR exists for a repo/branch (finds the open backflow PR)
./scripts/Get-CodeflowStatus.ps1 -Repository "dotnet/runtime" -CheckMissing -Branch "main"

# Check for missing PRs across all branches
./scripts/Get-CodeflowStatus.ps1 -Repository "dotnet/runtime" -CheckMissing
```

The script outputs a `[CODEFLOW_SUMMARY]` JSON block followed by a text summary. **Parse the JSON** — it contains:
- **`status`**: MERGED / CLOSED / NO-OP / IN_PROGRESS / STALE / ACTIVE
- **`vmrComparison.aheadBy`**: How many VMR commits behind (the *real* staleness number)
- **`forwardFlow.prs[]`**: All open forward flow PRs with their state
- **`warnings[]`**: Maestro staleness and conflict warnings extracted from PR comments
- **`subscription.id`**: For use with MCP remediation tools
- **`build.id`**: BAR build ID for triggering

### Step 2: After the Script — Use Its Output

🚨 The script already collected PR metadata, VMR commit distances, forward flow PRs, and Maestro warnings. **Do NOT re-query this data.** Instead:

1. **Read the `[CODEFLOW_SUMMARY]` JSON** and extract key facts:
   - `vmrComparison.aheadBy` = how far behind (this is VMR commits, NOT builds)
   - `forwardFlow.prs` = what's blocking backflow (open forward flow = blocked by design)
   - `warnings` = staleness/conflict details from Maestro comments
   - `commits.mergeCommitDetails` = merge commits on the PR (who merged `main` and when — note: merging `main` does NOT resolve staleness)
   - `status` = overall PR health classification

2. **Use MCP tools only for enrichment** the script can't provide:
   - Check **build freshness** — are VMR builds healthy? (channel-level, not per-PR)
   - Check **subscription history** — timeline of when the subscription got stuck (if script shows STALE)
   - **Trigger the subscription** — to remediate a stuck subscription (needs subscription ID + build ID from script output)

3. **Synthesize** script data + MCP enrichment into a diagnosis and recommendation.

> 💡 **No open PR?** If `-Repository`/`-Branch` finds no open backflow PR, the script reports this. Look up the **tracked PR for the subscription** to check Maestro's view, then check the most recently merged matching PR. A missing PR with a healthy subscription means flow is working normally.

### Step 3: Trace a Fix (Optional)

To check if a specific fix has reached the PR:
1. Read `src/source-manifest.json` from the VMR at the PR's snapshot commit — find the product repo's `commitSha`
2. Check if the fix commit is an ancestor of that SHA

## Flow Health Workflow (Script + MCP)

Flow health scanning uses a **hybrid approach**: the `flow-health.cs` script handles batch GitHub API calls in parallel, while maestro MCP tools provide subscription and build freshness data.

> 💡 **Why a script for flow health?** Scanning all branches requires 10-30+ parallel GitHub API calls (PR searches, body fetches, VMR HEAD lookups, commit comparisons). The script fires these in parallel using `Task.Run`; sequential MCP calls would be prohibitively slow.

### Step 1: Run the Script

```shell
# Scan all branches for a repo
dotnet ./scripts/flow-health.cs -- dotnet/sdk

# Scan a specific branch only
dotnet ./scripts/flow-health.cs -- dotnet/sdk --branch main
```

The script outputs structured JSON with:
- **`backflow.branches[]`**: Per-branch status (healthy/stale/conflict/missing/up-to-date/released-preview), PR numbers, VMR commit mapping, ahead-by counts, **CI status** (`ciStatus`: green/red/pending/none, `ciFailedCount`/`ciTotalCount` when red)
- **`backflow.summary`**: Counts of healthy/upToDate/blocked/missing branches
- **`forwardFlow.prs[]`**: Open forward flow PRs with health status
- **`forwardFlow.summary`**: Counts of healthy/stale/conflicted forward PRs

### Step 2: Enrich with Maestro MCP Data

After the script runs, enrich with maestro data:

1. **Build freshness**: For each `vmrBranch` found in the script output, check build freshness with the channel short name to verify official VMR builds are healthy.

2. **Subscription health**: For branches with `status: "missing"`, check subscription health for the target repository to diagnose *why* — is the subscription stuck, disabled, or is the channel frozen?

3. **Update history**: For stuck subscriptions, check the subscription's update history to see the timeline — when was the last successful application? Was there a failed attempt?

4. **Tracked PRs**: Cross-reference script results with the codeflow PR list to see Maestro's view of tracked PRs — the script sees GitHub state while Maestro may have a different picture.

5. **Latest builds**: For stuck subscriptions, find the latest build to get the buildId needed for triggering.

### Step 3: Synthesize

Combine script output (GitHub PR state) + MCP data (Maestro health) to produce the diagnosis:
- If multiple branches show `missing` AND build freshness is stale → VMR build failure (not a Maes

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [dotnet](https://github.com/dotnet)
- **Source:** [dotnet/arcade-skills](https://github.com/dotnet/arcade-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-dotnet-arcade-skills-flow-analysis
- Seller: https://agentstack.voostack.com/s/dotnet
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
