Module 7: Strategy To Roadmap
Mini-project: the strategic filter over Mercado's backlog
Description
It's time to bring the whole module together into a single deliverable. You learned to translate strategy into labeled bets (lesson 2), built the complete strategicFilter (lesson 3), saw the exact trap of a high riceScore outside strategy (lesson 4), measured whether approved bets reinforce each other (lesson 5), learned to communicate the NO with a real reason (lesson 6), and connected the filter with RICE in the right order (lesson 7). In this project you run the complete flow on Mercado's six-bet backlog —the five from product-thinking-for-engineers-guide plus the trap bet— and produce the quarter's final roadmap, verified with code at every step.
Your deliverable has three parts, and all three are verified with code, not just written up: (1) the complete backlog, run through strategicFilter against Mercado's strategy; (2) the final roadmap, sequenced with riceScore only among the bets that passed the filter; and (3) the explicit comparison against what a pure, unfiltered RICE ranking would have produced — the final demonstration of why the order of the two tools matters.
Connection to the module. This project introduces no new concept — it brings together, in a single verified flow, everything you built lesson by lesson. It's also the closing of the entire guide: the strategy you defined in modules 2 through 6 —vision, segment, positioning, differentiation, competition, moats— reaches its final destination here, turned into a concrete, defensible roadmap.
An analogy: the control tower, with the whole airport running
The module opened with a single passenger's security check: whoever has a valid pass gets through, no matter how organized everyone else is. This project is the moment to go up to the control tower and see the whole airport running at once: six candidate flights arriving at the terminal, each first going through security check —does it belong to the game Mercado chose to play?—, and only the ones that pass then appear on the departures board, ordered by their exact takeoff time —the riceScore, applied only among those who already qualified. A tower controller who only looked at the departures board, without having first verified every flight has a valid pass, would end up authorizing takeoffs that never should have been on the runway. This project is the complete, end-to-end view of a system that never makes that mistake.
The reference solution, verified
Part 1 — The complete backlog, run through strategicFilter
This is Mercado's complete quarter backlog: the five bets you already know from product-thinking-for-engineers-guide (module 3), plus the sixth trap bet this guide added —lowestPriceMatch—, each with the strategic dimension it claims to serve and its riceScore already calculated.
// Mini-project: applies Mercado's strategic filter to its complete
// backlog, then sequences the final roadmap with RICE, ONLY among the
// bets that passed the filter.
function riceScore({ reach, impact, confidence, effort }) {
return (reach * impact * confidence) / effort;
}
function strategicFilter(backlog, strategy) {
return backlog.map((bet) => {
const reinforces = bet.servesDimensions.filter((d) => strategy.winOn.includes(d));
const conflicts = bet.servesDimensions.filter((d) => strategy.avoid.includes(d));
return {
feature: bet.feature,
servesDimensions: bet.servesDimensions,
reinforces,
conflicts,
inStrategy: reinforces.length > 0 && conflicts.length === 0,
riceScore: Number(riceScore(bet.rice).toFixed(2)),
};
});
}
function prioritize(items) {
return items.slice().sort((a, b) => b.riceScore - a.riceScore);
}
// --- Mercado's strategy, as defined in modules 2-6 ---
const mercadoStrategy = { winOn: ['curatedDiscovery', 'sellerTrust'], avoid: ['price'] };
// --- The complete quarter backlog (product-thinking, module 3) + the trap bet ---
const backlog = [
{ feature: 'fasterCheckout', servesDimensions: ['convenience'], rice: { reach: 8000, impact: 2, confidence: 0.8, effort: 2 } },
{ feature: 'recommendations', servesDimensions: ['curatedDiscovery'], rice: { reach: 5000, impact: 1, confidence: 0.5, effort: 3 } },
{ feature: 'sellerTools', servesDimensions: ['sellerTrust'], rice: { reach: 1200, impact: 2, confidence: 0.8, effort: 2 } },
{ feature: 'reviews', servesDimensions: ['sellerTrust'], rice: { reach: 6000, impact: 0.5, confidence: 0.8, effort: 1 } },
{ feature: 'improvedSearch', servesDimensions: ['catalogBreadth'], rice: { reach: 9000, impact: 1, confidence: 0.5, effort: 3 } },
{ feature: 'lowestPriceMatch', servesDimensions: ['price'], rice: { reach: 9500, impact: 3, confidence: 0.8, effort: 3 } },
];
console.log('=== PART 1: the complete backlog, run through strategicFilter ===\n');
const filtered = strategicFilter(backlog, mercadoStrategy).sort((a, b) => b.riceScore - a.riceScore);
console.table(filtered.map((b) => ({
feature: b.feature,
servesDimensions: b.servesDimensions.join(', '),
inStrategy: b.inStrategy,
riceScore: b.riceScore,
})));
const eligible = filtered.filter((b) => b.inStrategy);
const rejected = filtered.filter((b) => !b.inStrategy);
console.log('\n=== PART 2: the final roadmap -- RICE, only among those who passed the filter ===\n');
const roadmap = prioritize(eligible);
console.table(roadmap.map((b) => ({ feature: b.feature, riceScore: b.riceScore })));
console.log('Mercado\'s roadmap: ' + roadmap.map((b) => b.feature).join(' > ') + '.');
console.log('\n=== PART 3: what the filter avoided ===\n');
const top2ByRiceAlone = filtered.slice(0, 2);
console.log('The 2 highest-riceScore bets in the WHOLE backlog: ' +
top2ByRiceAlone.map((b) => b.feature + ' (' + b.riceScore + ')').join(' and ') + '.');
console.log('Neither has inStrategy: true -- ' +
top2ByRiceAlone.map((b) => b.feature + '=' + b.inStrategy).join(', ') + '.');
console.log('Bets discarded by the filter: ' + rejected.map((b) => b.feature + ' (riceScore=' + b.riceScore + ')').join(', ') + '.');
What to expect. Running the file with Node produces exactly this output:
=== PART 1: the complete backlog, run through strategicFilter ===
┌─────────┬────────────────────┬────────────────────┬────────────┬───────────┐
│ (index) │ feature │ servesDimensions │ inStrategy │ riceScore │
├─────────┼────────────────────┼────────────────────┼────────────┼───────────┤
│ 0 │ 'lowestPriceMatch' │ 'price' │ false │ 7600 │
│ 1 │ 'fasterCheckout' │ 'convenience' │ false │ 6400 │
│ 2 │ 'reviews' │ 'sellerTrust' │ true │ 2400 │
│ 3 │ 'improvedSearch' │ 'catalogBreadth' │ false │ 1500 │
│ 4 │ 'sellerTools' │ 'sellerTrust' │ true │ 960 │
│ 5 │ 'recommendations' │ 'curatedDiscovery' │ true │ 833.33 │
└─────────┴────────────────────┴────────────────────┴────────────┴───────────┘
=== PART 2: the final roadmap -- RICE, only among those who passed the filter ===
┌─────────┬───────────────────┬───────────┐
│ (index) │ feature │ riceScore │
├─────────┼───────────────────┼───────────┤
│ 0 │ 'reviews' │ 2400 │
│ 1 │ 'sellerTools' │ 960 │
│ 2 │ 'recommendations' │ 833.33 │
└─────────┴───────────────────┴───────────┘
Mercado's roadmap: reviews > sellerTools > recommendations.
=== PART 3: what the filter avoided ===
The 2 highest-riceScore bets in the WHOLE backlog: lowestPriceMatch (7600) and fasterCheckout (6400).
Neither has inStrategy: true -- lowestPriceMatch=false, fasterCheckout=false.
Bets discarded by the filter: lowestPriceMatch (riceScore=7600), fasterCheckout (riceScore=6400), improvedSearch (riceScore=1500).
Walk through the result part by part and recognize what each one certifies:
- Part 1: of the six bets in the complete backlog, exactly three pass the strategic filter — and they're nowhere near the highest-
riceScoreones. The two most "profitable" bets in the complete backlog, per the expected-value-per-cost criterion, are markedinStrategy: false, each with its own reason:lowestPriceMatchcompetes on a rejected dimension;fasterCheckoutsimply doesn't reinforce either of the two dimensions where Mercado chose to win. - Part 2: the final roadmap —
reviews > sellerTools > recommendations— comes from applying RICE only to the three eligible bets, never to the original six. It's the samericeScore, the exact same formula you already knew fromproduct-thinking-for-engineers-guide, applied to a set already refined by strategic belonging. - Part 3: the final comparison leaves the module's complete argument with no ambiguity. If the Mercado team had built its roadmap directly from the pure RICE ranking —without the filter you built in this module—, the first two bets to ship would have been, precisely, the two that least advance the strategy it took five complete modules to define.
Common mistakes
Delivering the roadmap without showing the rejected bets. What happens: the team presents the final result —reviews > sellerTools > recommendations— as if it were obvious, without mentioning that lowestPriceMatch and fasterCheckout had a higher riceScore and were deliberately rejected. Why it happens: showing only what's actually going to be built feels cleaner and more action-oriented than also explaining what was decided not to build and why. How to spot it: if your roadmap deliverable includes no mention of the rejected bets or their riceScore, a stakeholder who knew the complete backlog is going to ask, sooner or later, "what about fasterCheckout?" — and the answer improvised in that moment is much weaker than a reason prepared in advance. How to fix it: always include this project's Part 3 —the explicit comparison— in any real roadmap deliverable: the filter only proves its value when you see, with numbers, what it decided not to go with.
Treating the capstone as just code, without the strategy's full narrative. What happens: the team delivers working code —strategicFilter, prioritize, the correct tables— but without connecting the result to modules 2 through 6's decisions: why winOn is exactly those two dimensions and not others, why avoid includes price. Why it happens: once the code runs and produces the correct result, it feels like the work is done — but the code, alone, doesn't explain why the strategy is what it is. How to spot it: if someone new to the team can run your code and get the correct roadmap, but can't explain why mercadoStrategy has those specific values, the narrative got lost along the way. How to fix it: every deliverable from this project should be able to trace, in one sentence, each value of winOn and avoid back to a specific module of this guide — curatedDiscovery and sellerTrust come from module 3's positioning; avoid: price comes from module 2's vision and gets confirmed on module 5's competitive map.
Not connecting the result to the quarter's real capacity. What happens: the team delivers the ordered roadmap —reviews > sellerTools > recommendations— and calls the conversation closed, without checking how many of those three bets actually fit within the quarter's available capacity. Why it happens: the filter and the order feel like the complete deliverable, when in reality —just as in product-thinking-for-engineers-guide's module 3 project— the last step of cutting by real capacity is missing. How to spot it: if your team can't say how many person-months it has available this quarter or where the list gets cut, the roadmap is ordered but not yet, actually, decided. How to fix it: sum the effort of the eligible bets in roadmap order (reviews: 1, sellerTools: 2, recommendations: 3) against the team's real capacity, exactly as you practiced in product-thinking-for-engineers-guide — the strategic filter and RICE decide the order; capacity decides where the list gets cut.
Exercises
Exercise 1 — Add a seventh bet to the backlog. An engineer proposes sellerVerificationBadges —a visible seal certifying a seller passed an identity verification process—, with rice: { reach: 3000, impact: 2, confidence: 0.8, effort: 1 }. Decide its servesDimensions, calculate its riceScore, and determine whether it would pass strategicFilter with Mercado's strategy.
See solution
servesDimensions: ['sellerTrust'] is the honest label — an identity verification seal is, directly, a trust signal about the seller. riceScore = (3000 × 2 × 0.8) / 1 = 4800 / 1 = 4800. With reinforces: ['sellerTrust'] (not empty) and conflicts: [] (doesn't compete on price), inStrategy would be true. In fact, with a riceScore of 4800, this hypothetical bet would enter the roadmap above reviews (2400), becoming the quarter's new leading bet — a good example that the filter doesn't punish high numbers, it just requires that number to come with real belonging.
Exercise 2 — Recalculate the roadmap with the seventh bet included. Using exercise 1's result, write out the new complete roadmap order (only among eligible bets) including sellerVerificationBadges.
See solution
With sellerVerificationBadges (4800) added to the three original eligible bets (reviews: 2400, sellerTools: 960, recommendations: 833.33), the new roadmap ordered by riceScore would be: sellerVerificationBadges (4800) > reviews (2400) > sellerTools (960) > recommendations (833.33). Notice that this new bet has a riceScore (4800) lower than the two rejected bets from the original backlog (lowestPriceMatch: 7600, fasterCheckout: 6400) — and that doesn't matter at all: what decides its place on the roadmap is its position among the eligible bets, not a direct comparison against bets that never qualified to compete. A riceScore of 4800 that does belong to the strategy is worth more, for the roadmap, than a riceScore of 7600 that doesn't — that's, in a single number, the module's whole thesis.
Exercise 3 — Present the filter and final roadmap to Mercado's founding team. Write, in a paragraph, how you'd present this project's three parts —the filter, the roadmap, and the comparison against pure RICE— to Mercado's founding team, closing with what this complete guide let them build.
See solution
A sample answer: "This quarter we started with six candidate bets. Before looking at which had the best number, we asked all six whether they belonged to the game we decided to play: curated discovery and seller trust, not price or generic convenience. Three passed that test —reviews, sellerTools, recommendations—, and we sequenced them with the same RICE formula we already used, now applied only among them: reviews first, then sellerTools, then recommendations. The other three —including the two bets with the best raw expected performance in the whole backlog— are out, each with a specific reason, not for lack of time. This is the direct result of all the strategy work we did: the vision that told us where we're going, the segment and positioning that chose who we serve first, the differentiation that confirmed we don't compete on parity, the competitive map that showed us the open space, the moats that told us what to defend, and now, finally, the filter that turns all of that into the exact list of what we're building this quarter — and, with the same clarity, into the list of what we decided not to build, even when the number said otherwise."
Summary and next step
In this mini-project you brought the whole module together into a single verified flow: Mercado's six-bet backlog run through strategicFilter (three eligible, three rejected, each with its reason), the final roadmap sequenced with riceScore only among the eligible ones (reviews > sellerTools > recommendations), and the final comparison against what a pure RICE ranking would have produced —led by the two bets Mercado's strategy, rightly, rejects. With this you close module 7.
Where you go next. You now have this guide's seven complete pieces: vision (module 2), segment and positioning (module 3), differentiation (module 4), competition and market (module 5), moats (module 6), and the filter that brings all of it down to the roadmap (this module). Module 8, the guide's final capstone, asks you to build Mercado's product strategy from start to finish, in a single document — the complete strategy one-pager, with all the logic run in Node, closing the entire arc of product-strategy-for-engineers-guide and connecting, one last time, with product-thinking-for-engineers-guide: the guide that chooses the game, handing the result to the guide that plays it.
Resources
- Roger Martin, "Decoding the Strategy Choice Cascade" — rogermartin.medium.com/decoding-the-strategy-choice-cascade-475d40555eb1. Playing to Win's complete framework, worth rereading now that you have your own, code-executed version of how a cascade of strategic choices ends in a concrete roadmap action. In English.
- Melissa Perri, Escaping the Build Trap — oreilly.com/library/view/escaping-the-build/9781491973767. The complete diagnosis of the trap —building with no connection to a real strategy—, now with the exact tool, in code, to avoid it in any future backlog. In English.
- Marty Cagan (Silicon Valley Product Group), "Product Strategy" — svpg.com/product-strategy-overview. Cagan closes the whole module's argument: product strategy only has real value the day it decides what gets built and what doesn't — exactly this project's result. In English.
- Itamar Gilad, "Why You Should Stop Using Product Roadmaps and Try GIST Planning" — itamargilad.medium.com/why-i-stopped-using-product-roadmaps-and-switched-to-gist-planning-3b7f54e271d1. The natural bridge to module 8: a roadmap that traces every line back to an explicit goal, exactly like the complete trace you built in this project. In English.