MoSCoW Prioritization for Salesforce Backlog
This skill activates when a Salesforce delivery team needs to prioritize a backlog of user stories or change requests for a sprint, release, or roadmap horizon. It produces a fixed-shape prioritized backlog: each row carries a MoSCoW tag, an effort tier, a value tier, an optional WSJF tie-break score, a release target, and a one-line rationale. The output is the canonical handoff into the release-train-planner, the orchestrator, and the deployment-risk-scorer agents.
Before Starting
Gather this context before running a prioritization session:
- Is the sponsor or product owner in the room? MoSCoW is a negotiated taxonomy, not a survey. If the person who owns the budget or the business outcome is not present, the output is provisional and must be reviewed before commit.
- Is the sizing convention agreed? This skill assumes the team has already adopted a sizing convention (T-shirt S/M/L/XL, Fibonacci, or person-days). If sizing is contested, stop and resolve that first — MoSCoW without a shared effort signal is theatre.
- Is the team capacity known and stable? Capacity must be expressed in the same unit as effort tiers (e.g., person-days remaining in the sprint after meetings, leave, support rotation). The Must commit is bounded by capacity, not by enthusiasm.
- Is each backlog item written as a Salesforce-ready user story? If stories are vague ("improve case management"), prioritization is meaningless. Refer to
admin/user-story-writing-for-salesforceand finish that first.
Core Concepts
The MoSCoW Rubric
MoSCoW comes from DSDM/Agile Project Framework and forces every backlog item into one of four named buckets. The discipline is in the definitions, not in the act of labelling.
| Bucket | Meaning | Effort cap | What happens if it slips |
|---|---|---|---|
| Must have (M) | Release fails its objective if not delivered: regulator requires it, contractual deadline depends on it, org won't function without it | DSDM canon: ≤ ~60% of total release effort. Above 60% → overcommitted, at risk | Release fails — escalate, re-tag, or extend horizon |
| Should have (S) | Important and high-value, but not release-breaking | None, but commit cap: Must + Should ≤ ~80% of capacity | Release ships; stakeholders unhappy. Natural overflow when capacity is tight |
| Could have (C) | Nice to have. Polish, reporting refinements, minor UX upgrades | Stretch goals only — fill slack, never commit | Buffer that absorbs estimate misses on Musts/Shoulds |
| Won't have — this release (W) | Agreed-out for current horizon; candidate for a future release | n/a | Goes back to backlog tagged for re-grooming |
| Won't have — ever (W) | Permanently out of scope (regulatory, architectural, strategic) | n/a | Archive with documented rationale — do not let it ferment |
The most common MoSCoW failure mode is everything-is-Must. If the backlog has more than ~60% Must by effort, the rubric has degraded into a wishlist and the prioritization session has not actually happened.
The Effort + Value Lens
MoSCoW alone is a coarse signal. Pair every item with two orthogonal scales so the team can sort within a bucket and detect cheap wins:
Effort tier (S/M/L/XL):
| Tier | Indicative scope |
|---|---|
| S | Half a day or less (a field, a list view, a permission set tweak) |
| M | One to three days (a record-triggered flow, a small report bundle, a validation rule pack) |
| L | Three to ten days (a multi-object flow, a Lightning page redesign, an Apex trigger refactor) |
| XL | More than ten days (a new object model, an integration, a Lightning component suite). XL items in a sprint are a smell — split. |
Value tier (1–5): business value as judged by the sponsor.
| Tier | Indicative business value |
|---|---|
| 5 | Strategic; tied to a board-level OKR or a regulatory deadline |
| 4 | High; closes a meaningful pain point or unlocks revenue |
| 3 | Solid; clear ROI but not strategic |
| 2 | Incremental; small productivity gain |
| 1 | Cosmetic; gold-plating |
The (effort, value) pair is the crucial second signal. A "Must, XL, value 2" row is almost certainly miscategorized and should be challenged.
WSJF as the Tie-Break
When MoSCoW + effort + value still produce ties — typically a cluster of "Must, M, value 4" items competing for the same sprint slot — escalate to WSJF (Weighted Shortest Job First) from SAFe:
WSJF = Cost of Delay / Job Size
Cost of Delay = User-Business Value + Time Criticality + Risk Reduction / Opportunity Enablement
Each component is scored on the modified Fibonacci 1, 2, 3, 5, 8, 13. Job Size uses the same scale (or the team's existing effort points). Sort descending: highest WSJF wins the slot.
WSJF is a tie-break, not a replacement for MoSCoW. Do not rank the entire backlog by WSJF — the cognitive cost is high and the comparative scoring degrades quickly past 15–20 items.
The Release Commit Rule
Once items are tagged, commit them to a release or sprint with this rule:
- Sum of Must effort ≤ team capacity for the horizon
- Sum of Must + Should effort ≤ ~80% of capacity (leaves slack for estimate misses and unplanned support)
- Could items fill any remaining slack but are explicitly stretch goals, not commitments
If Must alone exceeds capacity, the prioritization is invalid: either capacity must be raised (more people, longer horizon) or items must be re-tagged. The stalemate is the signal — do not paper over it by promising and missing.
Common Patterns
Pattern: Capacity-Bounded Sprint Commit
When to use: Two-week sprints with a stable team.
How it works:
- Compute capacity: (team size × sprint days) − (leave + support rotation + ceremonies). Express in the team's effort unit.
- Tag every backlog candidate M/S/C/W with rationale.
- Attach effort tier and value tier to every M and S item (W and C items can be effort-tagged later).
- Sum Must effort. If > capacity, escalate to the sponsor: cut, defer, or raise capacity.
- Sum Must + Should effort. Cap at ~80% of capacity. The remainder is the Could stretch zone.
- Record
release_targetfor every committed row; set Won't-this-release rows to the next horizon and Won't-ever rows toarchived.
Why not just the top-N stories: Top-N ignores effort. Six "value 5, XL" items overcommit a sprint that easily holds twelve "value 4, S" items.
Pattern: WSJF Tie-Break Workshop
When to use: When MoSCoW labelling produces a cluster of indistinguishable Musts that exceed sprint capacity.
How it works:
- Pull only the tied cluster into a worksheet (typically 5–15 rows).
- For each row, score: User-Business Value (1–13), Time Criticality (1–13), Risk Reduction / Opportunity Enablement (1–13), Job Size (1–13).
- Compute WSJF = (UBV + TC + RR/OE) / JS.
- Sort descending. The top items take the available slots; the rest become Should-have for the next horizon.
- Persist the score in the row's
wsjf_scorecolumn so the rationale is auditable.
Why not skip WSJF and just argue: Argument scales badly past three people. WSJF gives the team a shared rubric; the score is the artefact, not the verdict.
Decision Guidance
| Situation | Recommended Approach | Reason |
|---|---|---|
| Backlog has >60% Must by effort | Stop and re-tag — the rubric has collapsed | Everything-is-Must means nothing is prioritized |
| Item is regulatory or contractually due this release | Must, value 5, with effort tier | Regulatory deadlines are non-negotiable but still need sizing |
| Sponsor cannot decide between two Musts of equal effort | Run WSJF on just the tied pair | Tie-break with a shared rubric beats arguing |
| Item has been Won't for three releases running | Reclassify Won't-ever and archive | Stale Won't items pollute backlog grooming sessions |
| Effort estimate is XL | Split the story before prioritizing | XL items hide complexity; they distort capacity math |
| Item is "nice UX polish" | Could, value 1–2 | Polish is the buffer, not the commitment |
| Stakeholder wants Should re-tagged as Must mid-sprint | Reject — process churn is the larger cost | Re-prioritizing every sprint destroys throughput |
Recommended Workflow
Step-by-step instructions for an AI agent or practitioner activating this skill:
- Ingest the backlog — load every candidate as a row; verify each row has a story_id and a description sufficient to judge value and effort. Reject rows that are not real user stories.
- Tag MoSCoW — assign M / S / C / W to every row with a one-line rationale. Won't rows must be sub-tagged Won't-this-release vs Won't-ever.
- Attach effort tier — assign S / M / L / XL to every M and S row. Flag XL items for splitting before they are committed.
- Attach value tier — assign 1–5 to every M and S row, validated with the sponsor.
- WSJF tie-break — for any cluster of Musts that exceeds sprint capacity, score Cost of Delay / Job Size and persist
wsjf_score. - Commit Must to the current sprint or release — verify Sum(Must effort) ≤ capacity and Sum(Must+Should) ≤ ~80% of capacity. Set
release_targetfor every committed row. - Re-prioritize at backlog grooming — refresh tags only at the agreed grooming cadence (typically every two sprints). Avoid mid-sprint churn.
Handoff Schema
Every prioritized backlog row produced by this skill MUST conform to this JSON shape so downstream agents (release-train-planner, orchestrator, deployment-risk-scorer) can consume it:
{
"story_id": "STORY-1234",
"moscow": "M",
"moscow_subtag": null,
"effort": "M",
"value": 4,
"wsjf_score": null,
"release_target": "2026-Spring",
"rationale": "Regulator requires audit trail by end of FY26 Q3."
}
moscow— one ofM | S | C | Wmoscow_subtag— null for M/S/C; for W must bewon't-this-releaseorwon't-evereffort— one ofS | M | L | XLvalue— integer 1–5wsjf_score— number, populated only when WSJF tie-break was used; otherwise nullrelease_target— ISO-style release identifier orbacklog(Won't-this-release) orarchived(Won't-ever)rationale— one sentence; required for every W row, recommended for every M row
The canonical table form lives in templates/moscow-prioritization-for-sf-backlog-template.md.
Review Checklist
Run through these before handing the prioritized backlog to delivery:
- Every row has a MoSCoW tag (M/S/C/W) — no nulls
- Every Won't row has a sub-tag (Won't-this-release vs Won't-ever) and a rationale
- Every Must and Should row has effort and value tiers
- Sum of Must effort ≤ team capacity for the target horizon
- Sum of Must + Should effort ≤ ~80% of capacity
- Must items account for ≤ ~60% of backlog effort
- No XL items in the sprint commit (split first)
- WSJF was applied wherever Musts tied at the capacity boundary
- Sponsor or product owner signed off in the prioritization session
- Won't-ever rows have been archived, not left in the active backlog
Salesforce-Specific Gotchas
Non-obvious behaviours that cause real prioritization failures on Salesforce projects:
- Regulatory Musts that aren't actually Must — "Compliance wants it" is not the same as "the regulator will fine us if we don't ship by date X". Force a citation: which regulation, which clause, which deadline. Otherwise it goes Should.
- Won't-this-release ferments into Won't-ever silently — A row tagged Won't-this-release for four consecutive grooming cycles is no longer being deferred; it is being declined. Surface it for a real archive decision.
- Capacity inflated by counting full FTEs — A two-week sprint with five admins ≠ 50 admin-days. Subtract leave, support rotation, ceremonies, code review, and UAT participation. Real capacity is typically 50–60% of nominal.
- MoSCoW without effort hides infeasibility — A backlog of 80 Musts feels confident until the team realizes Must alone is 200 days of work for a 40-day sprint. Always pair MoSCoW with effort.
- Mid-sprint re-prioritization — Stakeholders frequently ask to swap a Must in once a sprint starts. The cost of churn (context switching, partial work abandoned, retests) is almost always higher than the cost of waiting one sprint.
Output Artifacts
| Artifact | Description |
|---|---|
| Prioritized backlog table | One row per story with story_id, moscow, effort, value, wsjf_score, release_target, rationale |
| Sprint or release commit list | The Must subset whose effort sum is within team capacity |
| Won't list (split) | Won't-this-release rows (return to backlog) vs Won't-ever rows (archived) with rationale |
| WSJF tie-break worksheet | For tied Must clusters: UBV, Time Criticality, RR/OE, Job Size, computed WSJF |
Related Skills
admin/user-story-writing-for-salesforce— author the stories before prioritizing themadmin/requirements-gathering-for-sf— finish discovery before tagging MoSCoWagents/release-train-planner/AGENT.md— consumes the prioritized backlog to plan releasesagents/orchestrator/AGENT.md— uses the release_target and effort signal to schedule which agents run when