Module 5: Mvp And Scoping
Mini-project: design the MVP that tests three Mercado bets, not the one that builds them entirely
Overview
It's time to bring the module's six lessons together into one complete exercise, applied to three real bets from Mercado's backlog: Product recommendations carousel, Product reviews and ratings, and Seller analytics dashboard —the same three you rewrote with their full causal chain in module 1's project—. You already know what makes a plan a real MVP and not a trimmed v1 (lesson 2), what can be cut for free and what can't (lesson 3), how to compare two plans' cost and moment of evidence (lesson 4), why the experiment's shape matters as much as its cost (lesson 5), how to trim a feature backlog down to its minimal core (lesson 6), and the five typical ways a plan fails to earn the name "MVP" (lesson 7). In this mini-project you're going to apply all of that, in order, to the three bets together.
The project has three parts, and all three get checked by running code, not by describing them in words. First, you compare the three bets —building each entirely against its corresponding MVP— reusing compareApproaches, and add up the results into a single total-effort table. Second, you trim the full backlog of candidate features for one of the three bets (Product reviews and ratings) down to its minimal subset, reusing selectMinimalScope. Third, you compare the total effort and moment of evidence of two possible paths for the quarter: building all three bets entirely, or building the three MVPs first.
How this connects to the module. This project introduces no new concept: it's the synthesis of the six previous lessons, applied end to end over three full bets at once, instead of just one. And it sets the stage for what comes next: identifying, within each of these bets, exactly which is the riskiest assumption —not just a reasonable assumption— is precisely the work module 6 is going to formalize in depth. And ordering the sequence in which to build these three MVPs, once you have evidence from all three, is the work of modules 3 (already done, with RICE) and 7 (the final roadmap, with cost of delay).
An analogy: the chef who tests three new recipes before the banquet
Go back to the module introduction's chef, who tastes a spoonful of a new recipe before cooking for 50. Now imagine the chef has, for the same banquet, three new candidate recipes for the menu —not just one—, and a limited ingredient budget for this week's tests. They don't test all three by cooking the whole pot of each —that would exhaust the testing budget with nothing left for the other two—. They taste a spoonful of each, with exactly the same proportions they'd use in the full version, and compare: which spoonfuls confirm the recipe is worth scaling, and which don't? With that evidence —cheap, fast, from all three at once— they decide which recipes are worth investing the full ingredient budget in for Saturday.
That's exactly what this project does with three bets from Mercado's backlog at once: instead of committing an entire quarter to building all three entirely, all three spoonfuls —the three MVPs— get tested first, and with that evidence, which ones to scale gets decided afterward.
The reference solution, verified
Let's build the project's three parts and verify them step by step. (The exercises at the end ask you to extend them and reason about new cases.)
Part 1 — The three bets, compared with compareApproaches
We start with the functions you already built in lessons 1 and 4, and with the three backlog bets —each with its risky assumption, its full plan, and its MVP—:
function compareApproaches(bet) {
const { name, riskiestAssumption, buildEverything, mvp } = bet;
const effortRatio = Math.round((mvp.effort / buildEverything.effort) * 100);
const sameEvidence = buildEverything.provesAssumption === mvp.provesAssumption;
return {
bet: name,
riskiestAssumption,
buildEverything: { effort: buildEverything.effort, evidenceAt: buildEverything.evidenceAt },
mvp: { effort: mvp.effort, evidenceAt: mvp.evidenceAt },
effortRatio,
sameEvidence,
};
}
function summarizeBets(bets) {
const results = bets.map(compareApproaches);
const totalBuildEverythingEffort = results.reduce((sum, r) => sum + r.buildEverything.effort, 0);
const totalMvpEffort = results.reduce((sum, r) => sum + r.mvp.effort, 0);
const totalSaved = totalBuildEverythingEffort - totalMvpEffort;
const totalSavedPercent = Math.round((totalSaved / totalBuildEverythingEffort) * 100);
return { results, totalBuildEverythingEffort, totalMvpEffort, totalSaved, totalSavedPercent };
}
// The three bets from Mercado's backlog this project trims.
const recommendationsBet = {
name: 'Product recommendations carousel',
riskiestAssumption: 'showing complementary products in the cart makes more buyers add a second product before paying',
buildEverything: { plan: 'recommendation engine with collaborative filtering and its own microservice', effort: 40, evidenceAt: 'day 40', provesAssumption: true },
mvp: { plan: 'fixed "bought together" table for the 20 highest-volume categories', effort: 4, evidenceAt: 'day 4', provesAssumption: true },
};
const reviewsBet = {
name: 'Product reviews and ratings',
riskiestAssumption: 'seeing a visible rating on the product page increases the likelihood a buyer completes the purchase',
buildEverything: { plan: 'full reviews system: text, photos, moderation, seller response, and helpfulness vote, across the whole catalog', effort: 20, evidenceAt: 'day 20', provesAssumption: true },
mvp: { plan: 'average star rating + count, seeded by hand with beta buyers, only in the 20 highest-traffic categories', effort: 3, evidenceAt: 'day 3', provesAssumption: true },
};
const sellerToolsBet = {
name: 'Seller analytics dashboard',
riskiestAssumption: 'if sellers see that products are moving slowly or running out of stock, they adjust price or stock in time, and that reduces lost sales',
buildEverything: { plan: 'full dashboard with real-time charts, automatic alerts, and export, for the 3000+ sellers', effort: 25, evidenceAt: 'day 25', provesAssumption: true },
mvp: { plan: 'weekly email report to 15 pilot sellers with their 5 worst-rotating products, generated by hand with a query', effort: 3, evidenceAt: 'day 3', provesAssumption: true },
};
console.log('=== Part 1: compareApproaches over the 3 bets ===\n');
const summary = summarizeBets([recommendationsBet, reviewsBet, sellerToolsBet]);
summary.results.forEach((r) => {
console.log(r.bet + ':');
console.log(' buildEverything: ' + r.buildEverything.effort + ' person-days, evidence ' + r.buildEverything.evidenceAt);
console.log(' mvp: ' + r.mvp.effort + ' person-days, evidence ' + r.mvp.evidenceAt);
console.log(' effortRatio: ' + r.effortRatio + '%, same key evidence: ' + r.sameEvidence + '\n');
});
console.log('Totals: build everything = ' + summary.totalBuildEverythingEffort + ' person-days | the 3 MVPs = ' +
summary.totalMvpEffort + ' person-days (' + summary.totalSavedPercent + '% of total) | savings: ' + summary.totalSaved + ' person-days');
This part holds no surprises per individual bet —each one repeats the pattern you already saw in lessons 1 and 4—, but summarizeBets adds something new: it brings all three together into a single total-effort view, exactly what a real team needs to plan the quarter, not bet by bet but as a set.
Part 2 — Trimming Product reviews and ratings's feature backlog
Of the three bets, we take one —reviews— and apply lesson 6's full algorithm to its proposed six-feature backlog:
function selectMinimalScope(features) {
const selected = features.filter((f) => f.provesTheBet);
const cut = features.filter((f) => !f.provesTheBet);
const totalCost = features.reduce((sum, f) => sum + f.cost, 0);
const selectedCost = selected.reduce((sum, f) => sum + f.cost, 0);
const savedCost = totalCost - selectedCost;
const savedPercent = Math.round((savedCost / totalCost) * 100);
return { selected: selected.map((f) => f.name), cut: cut.map((f) => f.name), totalCost, selectedCost, savedCost, savedPercent };
}
console.log('\n=== Part 2: selectMinimalScope over "Product reviews and ratings"\'s features ===\n');
const reviewsFeatures = [
{ name: 'Average star rating + count on the product page', cost: 3, provesTheBet: true },
{ name: 'Text field to write the review', cost: 5, provesTheBet: false },
{ name: 'Moderation and anti-spam filter for reviews', cost: 4, provesTheBet: false },
{ name: 'Seller response to the review', cost: 3, provesTheBet: false },
{ name: '"Was this review helpful" vote', cost: 2, provesTheBet: false },
{ name: 'Upload photos with the review', cost: 3, provesTheBet: false },
];
const scope = selectMinimalScope(reviewsFeatures);
console.log('selected: ' + scope.selected.join(', '));
console.log('cut: ' + scope.cut.join(', '));
console.log('total cost: ' + scope.totalCost + ' | MVP cost: ' + scope.selectedCost + ' | savings: ' + scope.savedCost + ' (' + scope.savedPercent + '%)');
Notice something that connects the two parts: reviewsBet's mvp.effort: 3 from Part 1 and this Part 2's selectedCost: 3 are the same number, calculated two different ways. In Part 1, 3 was an input you were already taking as given. In Part 2, that 3 comes from adding up, feature by feature, only the ones that prove the bet —it's the verification that the number you used in Part 1 wasn't a made-up figure, but the exact sum of the one backlog item that actually tests the central assumption.
Part 3 — Total effort vs. evidence obtained
With the two previous parts calculated, we close with the comparison a real team needs to decide the quarter:
console.log('\n=== Part 3: total effort vs evidence obtained ===\n');
console.log('Building the 3 full bets: ' + summary.totalBuildEverythingEffort + ' person-days, first evidence between day 20 and day 40.');
console.log('Building the 3 MVPs: ' + summary.totalMvpEffort + ' person-days (' + summary.totalSavedPercent + '% of the effort), first evidence between day 3 and day 4.');
What to expect. When you run the full file (all three parts together) with Node, the output is exactly this:
=== Part 1: compareApproaches over the 3 bets ===
Product recommendations carousel:
buildEverything: 40 person-days, evidence day 40
mvp: 4 person-days, evidence day 4
effortRatio: 10%, same key evidence: true
Product reviews and ratings:
buildEverything: 20 person-days, evidence day 20
mvp: 3 person-days, evidence day 3
effortRatio: 15%, same key evidence: true
Seller analytics dashboard:
buildEverything: 25 person-days, evidence day 25
mvp: 3 person-days, evidence day 3
effortRatio: 12%, same key evidence: true
Totals: build everything = 85 person-days | the 3 MVPs = 10 person-days (88% of total) | savings: 75 person-days
=== Part 2: selectMinimalScope over "Product reviews and ratings"'s features ===
selected: Average star rating + count on the product page
cut: Text field to write the review, Moderation and anti-spam filter for reviews, Seller response to the review, "Was this review helpful" vote, Upload photos with the review
total cost: 20 | MVP cost: 3 | savings: 17 (85%)
=== Part 3: total effort vs evidence obtained ===
Building the 3 full bets: 85 person-days, first evidence between day 20 and day 40.
Building the 3 MVPs: 10 person-days (88% of the effort), first evidence between day 3 and day 4.
Read the three parts together, because together they tell the project's full story. Part 1 confirms the 10-15% effort pattern isn't exclusive to a single bet: it repeats, with small variations, across all three —recommendations, reviews, and seller tools—. Part 2 verifies, with the full trimming algorithm, that the effort number you used in Part 1 for reviews's MVP wasn't arbitrary: it comes from adding up exactly the one feature in the proposed backlog that tests the central assumption, cutting the rest without losing any learning. And Part 3 translates all this into the real decision the team faces every quarter: 85 person-days and up to 40 days of waiting to build the three full bets, against 10 person-days and a maximum of 4 days of waiting to have real evidence about all three.
And notice what this result does not say, because it's as important as what it does say: 10 person-days of MVP don't replace the 85 of building everything —if all three assumptions get confirmed, that full work is still necessary afterward—. What this project demonstrates is that the team doesn't have to choose blindly, with only RICE's ranking (module 3) and the sized opportunity (module 4), which of the three bets to build entirely first. It can, for 12% of the quarter's total budget, get real evidence about all three before committing the rest — and decide with data, not with the confidence estimate declared before starting. That's exactly the bridge to module 6: once you have this evidence, the conversation stops being "which do we assume works better?" and becomes "which proved it works?".
Common mistakes
Applying selectMinimalScope to a bet without having first verified, with compareApproaches, that its MVP really costs a reasonable fraction of the total. What happens: the team trims a bet's feature backlog down to the minimum, but never compares that minimum against the cost of building the whole bet —they're left only with the list of cut features, without the effortRatio number that gives the trimming meaning—. Why it happens: the project's two parts use different data (a feature backlog against a two-alternative plan) and it's easy to treat them as separate exercises instead of two views of the same decision. How to spot it: the team can say "we cut five of six features" but can't say "that means the MVP costs X% of building everything". How to fix it: as in this project's Part 2, always verify that selectMinimalScope's selectedCost matches the mvp.effort you'd use in compareApproaches — they're the same figure, seen from two angles.
Presenting the total savings (88%) as if it applied equally to all three bets. What happens: someone cites "the MVP costs 88% less" as if it were a single, uniform number, applicable to any future backlog bet. Why it happens: a single aggregate number is easier to repeat than three different numbers (10%, 15%, 12%). How to spot it: the 88% figure gets used to justify a future MVP's expected cost without having calculated that specific MVP. How to fix it: 88% is the aggregate average of these three bets, with these estimated numbers — every new bet needs its own compareApproaches, with its own full plan and its own purpose-designed MVP. The aggregate figure is useful for communicating the general pattern to the rest of the organization, not for skipping the work of designing the next MVP.
Forgetting Part 3's "evidence obtained" is still a pedagogical model, not a measured result. What happens: "10 person-days, evidence in 4 days" gets presented as if it were already a proven fact of next quarter, instead of the projection of a plan not yet executed. Why it happens: this project's concrete numbers, precisely calculated by the code, feel more solid than a plain intention. How to spot it: the result gets cited in a meeting without clarifying it's effort estimates, not real measurements yet. How to fix it: as declared from the module's design, effort, evidenceAt, and provesTheBet are team estimates — this project's value is that it forces you to declare them explicitly and compare with judgment, not that it turns them into measured truths. Measuring whether the real evidence, once the MVPs are built, confirms or refutes each assumption is product-metrics-and-experimentation-guide's job.
Exercises
Exercise 1 — Add a fourth bet. Mercado's team also wants to evaluate Improved search (from lesson 4's exercise: buildEverything.effort: 35, mvp.effort: 5, both with provesAssumption: true). Add it to summarizeBets's array alongside the other three and recalculate the totals.
See solution
With four bets, totalBuildEverythingEffort = 40 + 20 + 25 + 35 = 120, totalMvpEffort = 4 + 3 + 3 + 5 = 15, totalSaved = 105, and totalSavedPercent = round((105 / 120) * 100) = 88 — the same aggregate percentage as with three bets, because all four share a similar individual effortRatio (between 10% and 15%). This confirms, with an independent fourth bet, that the pattern doesn't depend on which specific three bets you pick: it holds as long as each MVP is designed following lessons 2 through 6's same criterion, not by coincidence of these particular numbers.
Exercise 2 — What happens if a bet has no cheap MVP? Imagine a hypothetical fifth bet, Multi-country currency conversion, where there's no cheap way to test the assumption without building most of the real currency-conversion infrastructure (buildEverything.effort: 30, mvp.effort: 22, both provesAssumption: true). Calculate its effortRatio and explain in 2-3 sentences what a high effortRatio (say, above 60%) means for the team's decision, different from what you saw in the other four bets.
See solution
effortRatio = round((22 / 30) * 100) = 73. An effortRatio that high is a legitimate, honest signal, not a model error: it means that, for this specific bet, there's no experiment much cheaper than building almost the whole infrastructure —some bets, like deep infrastructure changes (currency, security, regulatory compliance), genuinely don't lend themselves to a thin MVP, because the central risk is in the infrastructure itself, not in user behavior—. In that case, the team's decision changes: instead of "let's build the cheap MVP first", the right question becomes whether it's worth investing 73% of the full effort just to reduce uncertainty, compared to other backlog bets that do have a much cheaper MVP — exactly the kind of comparison module 7 (cost of delay and the roadmap) picks back up.
Exercise 3 — The closing argument. Imagine you have to defend, to Mercado's leadership team, why it's worth investing two weeks of the quarter building the three MVPs before deciding which bet to scale first, instead of going straight to building the RICE-highest-scored bet (module 3) at full size. Use this project's concrete numbers to build the argument in 3-4 sentences.
See solution
One possible argument: "RICE tells us which bet we believe is worth the most, with the information we have today —but 'believe' is still a confidence estimate, not a fact—. For 10 of the 85 person-days it would cost to build all three bets entirely —12% of the budget—, we can have real evidence about all three in under a week, instead of betting the whole quarter on the one that scored highest at the meeting. If the evidence confirms RICE's ranking, we build with far more confidence than before. And if the evidence contradicts it —if the 'safe' bet turns out weak and one that scored lower turns out promising—, we save ourselves exactly the kind of costly mistake module 1's build trap describes: building a lot, with quality, in the wrong direction." The argument works because it doesn't ask for more total time —it asks to invest a small fraction first, so the rest of the budget gets spent with real evidence instead of a calculated hunch.
Summary and next step
In this mini-project you designed the MVP for three full bets from Mercado's backlog, bringing the module's six lessons together into a single verified workflow: you compared each full bet's effort and evidence against its MVP (lessons 1 and 4), trimmed reviews's feature backlog down to its minimal core with lesson 6's same criterion, and added up the results into the comparison a real team needs to plan a quarter: 85 person-days and up to 40 days of waiting to build everything, against 10 person-days and a maximum of 4 days of waiting to have real evidence about all three. And you saw, with the same honesty the whole module demands, that this saving doesn't replace the full work if the assumptions get confirmed —it postpones it until there's real evidence justifying it—.
With this you close module 5. You now have this whole guide's central instrument for the question "what do I build first, and how big?": never build the whole bet at once, but design, for each one, the cheapest experiment that genuinely tests —with the same conditions as a real MVP— whether it's worth building in full.
Where you go next. Module 6 takes exactly the risky assumptions you named across this project's three bets and treats them for what they are: bets under uncertainty. You're going to learn to separate facts from assumptions, to identify which assumption, if false, sinks the whole bet, and to connect RICE's confidence (module 3) with real evidence instead of a hunch. And further ahead: saying no with arguments and ordering the roadmap by cost of delay (module 7), all the way to the module 8 capstone, where you return to Mercado's full backlog one last time, with every tool in the guide together.
Resources
- Eric Ries, The Lean Startup — theleanstartup.com. Revisit it as the module's closing note: the "validated learning loop" is, in essence, this project repeated quarter after quarter. In English.
- Henrik Kniberg, "Making Sense of MVP" — blog.crisp.se/2016/01/25/henrikkniberg/making-sense-of-mvp. The skateboard drawing, reread now with three bets in mind instead of one: each Mercado bet has its own skateboard-to-car path. In English.
- Marty Cagan (Silicon Valley Product Group), Silicon Valley Product Group blog — svpg.com/articles. On why the best product teams test several cheap bets in parallel before committing to scale a single one. In English.
- Basecamp, "Shape Up" — basecamp.com/shapeup. As a bridge to module 7: on how to decide, with scope already trimmed, in what order bets enter a real work cycle. In English.