Weekly pipeline health analysis with velocity metrics, stage distribution, forecasting, and actionable recommendations
Pulls CRM data, calculates pipeline health metrics (total value, stage distribution, velocity, conversion rates, aging deals), compares performance to targets, generates a revenue forecast, and outputs a pipeline health report with prioritized recommendations. Designed to run weekly (typically Monday morning) but can be triggered ad hoc.
agency.config.json at repo root with agency, crm, outreach, services, and scoring sectionscrm-writer skill (Google Sheets webhook or API)crm-writer -- for reading pipeline data from CRM tabsrevenue-forecaster -- for weighted pipeline and Monte Carlo forecasting (if installed)win-loss-analyzer -- for historical conversion pattern data (if installed)agency.config.json from the project root.agency.name -- for report headercrm.type -- CRM platform (google_sheets, etc.)crm.sheet_id -- for data accesscrm.webhook_url -- for reading datacrm.tabs.pipeline -- pipeline data tab namecrm.tabs.outreach_log -- outreach activity datacrm.tabs.calling -- calling activity datacrm.tabs.dashboard -- where to write the report summaryoutreach.cadence -- to assess if cadence is being followedoutreach.daily_caps -- to assess if activity targets are being metscoring.thresholds -- hot/warm/cool definitionsservices[] -- for deal categorization by service typereview_period -- timeframe to analyze. Default: last_7_days. Options: last_7_days, last_14_days, last_30_days, mtd, qtdtargets -- (optional) revenue and activity targets:
monthly_revenue_target -- target MRR or monthly revenuequarterly_revenue_target -- target quarterly revenueweekly_demos -- target demos per weekweekly_proposals -- target proposals per weekdaily_outreach -- target outreach activities per daycompare_period -- compare to previous period for trend. Default: previous_weekforecast_months -- months to forecast. Default: 3output_to_crm -- write report summary to Dashboard tab. Default: truePull data from all relevant CRM tabs using crm-writer.
Pipeline data (from Pipeline tab):
Required pipeline stages (map to CRM columns):
LEAD -> QUALIFIED -> DEMO_SCHEDULED -> DEMO_DONE -> PROPOSAL_SENT -> NEGOTIATION -> CLOSED_WON -> CLOSED_LOST
If CRM uses different stage names, map them to these standard stages.
Outreach data (from Outreach CRM tab):
Historical data (from Pipeline tab, all time):
Compile raw data:
DATA COLLECTION:
---
Active deals: [count]
Deals in review period: [count]
Outreach activities in review period: [count]
Closed won (all time): [count]
Closed lost (all time): [count]
Data quality issues: [list any missing fields or inconsistencies]
Calculate the core metrics that determine pipeline health.
| Metric | Calculation |
|---|---|
| Total pipeline value | Sum of all active deal values |
| Weighted pipeline value | Sum of (deal value * stage probability) for all active deals |
| New pipeline added (period) | Sum of deals created during review period |
| Pipeline lost (period) | Sum of deals moved to CLOSED_LOST during review period |
| Net pipeline change | Added - Lost |
| Pipeline-to-target ratio | Weighted pipeline / revenue target |
Pipeline-to-target ratio benchmarks:
Count and value deals at each stage:
| Stage | Deal Count | Total Value | Avg Deal Size | % of Pipeline |
|---|---|---|---|---|
| LEAD | ||||
| QUALIFIED | ||||
| DEMO_SCHEDULED | ||||
| DEMO_DONE | ||||
| PROPOSAL_SENT | ||||
| NEGOTIATION |
Stage health indicators:
| Metric | Calculation |
|---|---|
| Average days in stage | For each stage, average days deals spend before moving |
| Average sales cycle | Average days from LEAD to CLOSED_WON |
| Stage-to-stage conversion rate | % of deals that advance from each stage to the next |
| Overall win rate | CLOSED_WON / (CLOSED_WON + CLOSED_LOST) |
| Velocity score | (# of deals * avg deal size * win rate) / avg sales cycle |
Velocity trend:
Identify stale deals that need attention:
| Aging Category | Definition | Action |
|---|---|---|
| Fresh | Last activity within 3 days | No action |
| Active | Last activity 4-7 days ago | Monitor |
| Cooling | Last activity 8-14 days ago | Follow up immediately |
| Stale | Last activity 15-30 days ago | Escalate: call or break-up |
| Dead | Last activity 30+ days ago | Move to CLOSED_LOST or archive |
List all COOLING and STALE deals with:
| Metric | Actual | Target | % of Target |
|---|---|---|---|
| Emails sent (period) | |||
| LinkedIn touches (period) | |||
| Instagram touches (period) | |||
| Calls made (period) | |||
| Total outreach activities | |||
| Response rate | |||
| Demos booked (period) | |||
| Proposals sent (period) |
Compare to outreach.daily_caps multiplied by business days in the period.
Analyze where deals are being won and lost.
LEAD -> QUALIFIED: [X%] conversion ([N] leads -> [M] qualified)
QUALIFIED -> DEMO: [X%] conversion
DEMO -> PROPOSAL: [X%] conversion
PROPOSAL -> WON: [X%] conversion
---
Overall LEAD -> WON: [X%] conversion
Identify the weakest conversion point -- this is where the biggest improvement opportunity exists.
| Segment | Deals Won | Deals Lost | Win Rate | Avg Deal Size |
|---|---|---|---|---|
| India D2C | ||||
| US/UK/AU D2C | ||||
| [Service 1] | ||||
| [Service 2] | ||||
| Inbound | ||||
| Outbound |
Identify the highest-performing segments by win rate and deal size.
If loss reasons are tracked in CRM, aggregate:
| Reason | Count | % of Losses | Trend |
|---|---|---|---|
| Price | up/down/stable | ||
| Timing | |||
| Went with competitor | |||
| No decision/ghosted | |||
| Scope mismatch |
Generate a revenue forecast based on pipeline data.
Apply stage-specific probabilities:
| Stage | Probability | Deal Value | Weighted Value |
|---|---|---|---|
| LEAD | 5% | ||
| QUALIFIED | 15% | ||
| DEMO_SCHEDULED | 25% | ||
| DEMO_DONE | 40% | ||
| PROPOSAL_SENT | 60% | ||
| NEGOTIATION | 80% |
Total weighted forecast: $[sum]
| Scenario | Method | Amount |
|---|---|---|
| Conservative | Only PROPOSAL + NEGOTIATION deals at 50% probability | $X |
| Moderate | Weighted pipeline (all stages) | $Y |
| Best case | All active deals at stage probability + historical win rate adjustment | $Z |
Based on expected close dates:
| Month | Deals Expected | Weighted Value | Confidence |
|---|---|---|---|
| This month | |||
| Next month | |||
| Month +2 |
Revenue target: $[target]
Weighted pipeline: $[weighted]
Coverage ratio: [weighted/target]x
---
Need to add: $[shortfall * 3] in new pipeline to hit target (at 3x coverage)
= [shortfall * 3 / avg_deal_size] new qualified leads needed
Compare current period to previous period(s).
| Metric | Current | Previous | Change | Trend |
|---|---|---|---|---|
| Total pipeline value | up/down | |||
| New deals added | ||||
| Deals closed (won) | ||||
| Win rate | ||||
| Average deal size | ||||
| Sales cycle length | ||||
| Outreach volume | ||||
| Response rate | ||||
| Velocity score |
Flag concerning trends:
Generate prioritized, actionable recommendations based on the analysis.
Recommendation categories:
Immediate actions (this week):
Process improvements (this month):
Strategic recommendations (this quarter):
Priority scoring for recommendations:
| Factor | Weight |
|---|---|
| Revenue impact | 40% |
| Effort required | 30% |
| Urgency (time-sensitive) | 30% |
Rank all recommendations by priority score. Top 3 become the "Weekly Focus."
Return structured JSON:
{
"report_metadata": {
"agency": "Agency Name",
"review_period": "2026-03-03 to 2026-03-09",
"generated_at": "2026-03-10T09:00:00Z",
"data_quality": "good",
"data_issues": []
},
"pipeline_snapshot": {
"total_value": 450000,
"weighted_value": 185000,
"deal_count": 18,
"avg_deal_size": 25000,
"new_this_period": 4,
"lost_this_period": 1,
"net_change": 75000,
"pipeline_to_target_ratio": 3.2,
"health": "healthy"
},
"stage_distribution": [
{"stage": "LEAD", "count": 5, "value": 125000, "pct_of_pipeline": 0.28},
{"stage": "QUALIFIED", "count": 4, "value": 100000, "pct_of_pipeline": 0.22},
{"stage": "DEMO_SCHEDULED", "count": 3, "value": 75000, "pct_of_pipeline": 0.17},
{"stage": "DEMO_DONE", "count": 2, "value": 50000, "pct_of_pipeline": 0.11},
{"stage": "PROPOSAL_SENT", "count": 3, "value": 75000, "pct_of_pipeline": 0.17},
{"stage": "NEGOTIATION", "count": 1, "value": 25000, "pct_of_pipeline": 0.06}
],
"stage_health": "slightly_top_heavy",
"velocity": {
"avg_sales_cycle_days": 28,
"velocity_score": 4821,
"velocity_trend": "stable",
"stage_durations": [
{"stage": "LEAD_to_QUALIFIED", "avg_days": 5},
{"stage": "QUALIFIED_to_DEMO", "avg_days": 7},
{"stage": "DEMO_to_PROPOSAL", "avg_days": 4},
{"stage": "PROPOSAL_to_CLOSE", "avg_days": 12}
]
},
"aging": {
"fresh": 8,
"active": 5,
"cooling": 3,
"stale": 2,
"dead": 0,
"attention_needed": [
{"company": "Company A", "value": 30000, "stage": "PROPOSAL_SENT", "days_stale": 12, "action": "Call this week -- proposal sent 12 days ago with no response"},
{"company": "Company B", "value": 20000, "stage": "QUALIFIED", "days_stale": 18, "action": "Re-engage or move to lost"}
]
},
"activity_metrics": {
"emails_sent": 22,
"linkedin_touches": 18,
"instagram_touches": 8,
"calls_made": 6,
"total_activities": 54,
"target_activities": 75,
"pct_of_target": 0.72,
"response_rate": 0.12,
"demos_booked": 2,
"proposals_sent": 1
},
"conversion_funnel": {
"lead_to_qualified": 0.65,
"qualified_to_demo": 0.55,
"demo_to_proposal": 0.70,
"proposal_to_won": 0.35,
"overall_lead_to_won": 0.09,
"weakest_point": "proposal_to_won",
"weakest_point_insight": "35% proposal-to-close rate suggests pricing objections or proposal quality issues"
},
"forecast": {
"weighted_total": 185000,
"scenarios": {
"conservative": 100000,
"moderate": 185000,
"best_case": 290000
},
"monthly_forecast": [
{"month": "March 2026", "weighted_value": 75000, "deal_count": 4},
{"month": "April 2026", "weighted_value": 65000, "deal_count": 3},
{"month": "May 2026", "weighted_value": 45000, "deal_count": 2}
],
"pipeline_coverage": {
"target": 150000,
"weighted_pipeline": 185000,
"ratio": 1.23,
"shortfall": 0,
"new_leads_needed": 0
}
},
"trends": {
"pipeline_value_trend": "up",
"win_rate_trend": "stable",
"deal_size_trend": "up",
"cycle_length_trend": "stable",
"activity_trend": "down",
"concerning_trends": ["Outreach activity 28% below target for 2nd consecutive week"]
},
"recommendations": {
"weekly_focus": [
{"priority": 1, "action": "Follow up on 3 cooling deals worth $70K combined", "category": "immediate", "revenue_impact": "high"},
{"priority": 2, "action": "Increase outreach volume to hit daily caps -- 28% below target", "category": "immediate", "revenue_impact": "medium"},
{"priority": 3, "action": "Review proposal template -- 35% close rate is below benchmark", "category": "process", "revenue_impact": "high"}
],
"immediate_actions": [],
"process_improvements": [],
"strategic_recommendations": []
}
}
After generating the report:
output_to_crm is true, write a summary row to the Dashboard tab via crm-writerPresent the pipeline review:
Trigger phrases:
User: Run a pipeline review for this week
Assistant: [reads config, pulls CRM data via crm-writer, calculates all metrics, identifies stale deals, generates forecast, compares to previous week, returns health report with 3 focus actions]
User: How is the pipeline looking? Any deals going stale?
Assistant: [pulls pipeline data, runs aging analysis, identifies cooling and stale deals, returns deal-level recommendations with urgency ranking]