Módulo 7: Strategy To Roadmap
Mini-proyecto: el filtro estratégico sobre el backlog de Mercado
Descripción
Es momento de juntar el módulo entero en una sola entrega. Aprendiste a traducir la estrategia en apuestas etiquetadas (lección 2), construiste strategicFilter completo (lección 3), viste la trampa exacta de un riceScore alto fuera de estrategia (lección 4), midieste si las apuestas aprobadas se refuerzan entre sí (lección 5), aprendiste a comunicar el NO con una razón real (lección 6), y conectaste el filtro con RICE en el orden correcto (lección 7). En este proyecto corres el flujo completo sobre el backlog de seis apuestas de Mercado —las cinco de product-thinking-for-engineers-guide más la apuesta trampa— y produces el roadmap final del trimestre, verificado con código en cada paso.
Tu entregable tiene tres partes, y las tres se verifican con código, no solo se redactan: (1) el backlog completo, pasado por strategicFilter contra la estrategia de Mercado; (2) el roadmap final, secuenciado con riceScore solo entre las apuestas que pasaron el filtro; y (3) la comparación explícita contra lo que un ranking de RICE puro, sin filtro, hubiera producido — la demostración final de por qué el orden de las dos herramientas importa.
Conexión con el módulo. Este proyecto no introduce ningún concepto nuevo — reúne, en un solo flujo verificado, todo lo que construiste lección por lección. Es, además, el cierre de la guía completa: la estrategia que definiste en los módulos 2 a 6 —visión, segmento, posicionamiento, diferenciación, competencia, moats— llega aquí a su destino final, convertida en un roadmap concreto y defendible.
Una analogía: la torre de control, con el aeropuerto completo funcionando
El módulo abrió con el control de seguridad de un pasajero individual: pasa quien tiene un pase válido, sin importar cuán organizado venga el resto. Este proyecto es el momento de subir a la torre de control y ver el aeropuerto completo en funcionamiento a la vez: seis vuelos candidatos llegando a la terminal, cada uno pasando primero por el control de seguridad —¿pertenece al juego que Mercado eligió jugar?—, y solo los que pasan aparecen, después, en el tablero de salidas, ordenados por su hora exacta de despegue —el riceScore, aplicado únicamente entre quienes ya calificaron—. Un controlador de torre que solo mirara el tablero de salidas, sin haber verificado antes que cada vuelo tiene un pase válido, terminaría autorizando despegues que nunca debieron estar en la pista. Este proyecto es la vista completa, de principio a fin, de un sistema que nunca comete ese error.
La solución de referencia, verificada
Parte 1 — El backlog completo, pasado por strategicFilter
Este es el backlog completo del trimestre de Mercado: las cinco apuestas que ya conoces de product-thinking-for-engineers-guide (módulo 3), más la sexta apuesta trampa que esta guía agregó —lowestPriceMatch—, cada una con la dimensión estratégica que dice servir y su riceScore ya calculado.
// Mini-proyecto: aplica el filtro estrategico de Mercado sobre su backlog
// completo, y despues secuencia el roadmap final con RICE, SOLO entre las
// apuestas que pasaron el filtro.
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);
}
// --- La estrategia de Mercado, tal como quedo definida en los modulos 2-6 ---
const mercadoStrategy = { winOn: ['curatedDiscovery', 'sellerTrust'], avoid: ['price'] };
// --- El backlog completo del trimestre (product-thinking, modulo 3) + la apuesta trampa ---
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('=== PARTE 1: el backlog completo, pasado por 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=== PARTE 2: el roadmap final -- RICE, solo entre quienes pasaron el filtro ===\n');
const roadmap = prioritize(eligible);
console.table(roadmap.map((b) => ({ feature: b.feature, riceScore: b.riceScore })));
console.log('Roadmap de Mercado: ' + roadmap.map((b) => b.feature).join(' > ') + '.');
console.log('\n=== PARTE 3: lo que el filtro evito ===\n');
const top2ByRiceAlone = filtered.slice(0, 2);
console.log('Las 2 apuestas de mayor riceScore de TODO el backlog: ' +
top2ByRiceAlone.map((b) => b.feature + ' (' + b.riceScore + ')').join(' y ') + '.');
console.log('Ninguna de las dos tiene inStrategy: true -- ' +
top2ByRiceAlone.map((b) => b.feature + '=' + b.inStrategy).join(', ') + '.');
console.log('Apuestas descartadas por el filtro: ' + rejected.map((b) => b.feature + ' (riceScore=' + b.riceScore + ')').join(', ') + '.');
Qué esperar. Al correr el archivo con Node, la salida es exactamente esta:
=== PARTE 1: el backlog completo, pasado por 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 │
└─────────┴────────────────────┴────────────────────┴────────────┴───────────┘
=== PARTE 2: el roadmap final -- RICE, solo entre quienes pasaron el filtro ===
┌─────────┬───────────────────┬───────────┐
│ (index) │ feature │ riceScore │
├─────────┼───────────────────┼───────────┤
│ 0 │ 'reviews' │ 2400 │
│ 1 │ 'sellerTools' │ 960 │
│ 2 │ 'recommendations' │ 833.33 │
└─────────┴───────────────────┴───────────┘
Roadmap de Mercado: reviews > sellerTools > recommendations.
=== PARTE 3: lo que el filtro evito ===
Las 2 apuestas de mayor riceScore de TODO el backlog: lowestPriceMatch (7600) y fasterCheckout (6400).
Ninguna de las dos tiene inStrategy: true -- lowestPriceMatch=false, fasterCheckout=false.
Apuestas descartadas por el filtro: lowestPriceMatch (riceScore=7600), fasterCheckout (riceScore=6400), improvedSearch (riceScore=1500).
Recorre el resultado por partes y reconoce lo que cada una certifica:
- Parte 1: de las seis apuestas del backlog completo, exactamente tres pasan el filtro estratégico — y no son, ni de lejos, las de mayor
riceScore. Las dos apuestas más "rentables" del backlog completo, según el criterio de valor esperado por costo, están marcadasinStrategy: false, cada una con su propia razón:lowestPriceMatchcompite en una dimensión rechazada;fasterCheckoutsimplemente no refuerza ninguna de las dos dimensiones donde Mercado eligió ganar. - Parte 2: el roadmap final —
reviews > sellerTools > recommendations— nace de aplicar RICE únicamente sobre las tres apuestas elegibles, nunca sobre las seis originales. Es el mismoriceScore, la misma fórmula exacta que ya conocías deproduct-thinking-for-engineers-guide, aplicada sobre un conjunto ya depurado por pertenencia estratégica. - Parte 3: la comparación final deja el argumento completo del módulo sin ambigüedad. Si el equipo de Mercado hubiera construido su roadmap directamente desde el ranking de RICE puro —sin el filtro que construiste en este módulo—, las dos primeras apuestas en salir a producción habrían sido, precisamente, las dos que menos avanzan la estrategia que le costó cinco módulos completos definir.
Errores comunes
Entregar el roadmap sin mostrar las apuestas rechazadas. Qué pasa: el equipo presenta el resultado final —reviews > sellerTools > recommendations— como si fuera obvio, sin mencionar que lowestPriceMatch y fasterCheckout tenían un riceScore más alto y fueron rechazadas deliberadamente. Por qué pasa: mostrar solo lo que sí se va a construir se siente más limpio y más orientado a la acción que explicar, además, lo que se decidió no construir y por qué. Cómo detectarlo: si tu entrega de roadmap no incluye ninguna mención de las apuestas rechazadas ni de su riceScore, un stakeholder que conocía el backlog completo va a preguntar, tarde o temprano, "¿y fasterCheckout?" — y la respuesta improvisada en ese momento es mucho más débil que la razón preparada de antemano. Cómo corregirlo: incluye siempre la Parte 3 de este proyecto —la comparación explícita— en cualquier entrega real de roadmap: el filtro solo demuestra su valor cuando se ve, con números, contra qué decidió no ir.
Tratar el capstone como solo código, sin la narrativa completa de la estrategia. Qué pasa: el equipo entrega el código funcionando —strategicFilter, prioritize, las tablas correctas— pero sin conectar el resultado con las decisiones de los módulos 2 a 6: por qué winOn es exactamente esas dos dimensiones y no otras, por qué avoid incluye precio. Por qué pasa: una vez que el código corre y produce el resultado correcto, se siente como que el trabajo está terminado — pero el código, solo, no explica por qué la estrategia es la que es. Cómo detectarlo: si alguien nuevo en el equipo puede correr tu código y obtener el roadmap correcto, pero no puede explicar por qué mercadoStrategy tiene esos valores específicos, la narrativa se perdió en el camino. Cómo corregirlo: cada entrega de este proyecto debería poder trazar, en una frase, cada valor de winOn y avoid de vuelta a un módulo específico de esta guía — curatedDiscovery y sellerTrust vienen del posicionamiento del módulo 3; avoid: price viene de la visión del módulo 2 y se confirma en el mapa competitivo del módulo 5.
No conectar el resultado con la capacidad real del trimestre. Qué pasa: el equipo entrega el roadmap ordenado —reviews > sellerTools > recommendations— y da por cerrada la conversación, sin verificar cuántas de esas tres apuestas caben, de verdad, dentro de la capacidad disponible del trimestre. Por qué pasa: el filtro y el orden se sienten como el entregable completo, cuando en realidad —igual que en el proyecto del módulo 3 de product-thinking-for-engineers-guide— falta el último paso de cortar por capacidad real. Cómo detectarlo: si tu equipo no puede decir cuántos person-months tiene disponibles este trimestre ni dónde se corta la lista, el roadmap está ordenado pero no está, todavía, decidido. Cómo corregirlo: suma el effort de las apuestas elegibles en el orden del roadmap (reviews: 1, sellerTools: 2, recommendations: 3) contra la capacidad real del equipo, exactamente como practicaste en product-thinking-for-engineers-guide — el filtro estratégico y RICE deciden el orden; la capacidad decide dónde se corta la lista.
Ejercicios
Ejercicio 1 — Agrega una séptima apuesta al backlog. Un ingeniero propone sellerVerificationBadges —un sello visible que certifica que un vendedor pasó un proceso de verificación de identidad—, con rice: { reach: 3000, impact: 2, confidence: 0.8, effort: 1 }. Decide su servesDimensions, calcula su riceScore, y determina si pasaría strategicFilter con la estrategia de Mercado.
Ver solución
servesDimensions: ['sellerTrust'] es la etiqueta honesta — un sello de verificación de identidad es, directamente, una señal de confianza en el vendedor. riceScore = (3000 × 2 × 0.8) / 1 = 4800 / 1 = 4800. Con reinforces: ['sellerTrust'] (no vacío) y conflicts: [] (no compite en precio), inStrategy sería true. De hecho, con un riceScore de 4800, esta apuesta hipotética entraría al roadmap por encima de reviews (2400), convirtiéndose en la nueva apuesta líder del trimestre — un buen ejemplo de que el filtro no castiga los números altos, solo exige que ese número venga acompañado de pertenencia real.
Ejercicio 2 — Recalcula el roadmap con la séptima apuesta incluida. Usando el resultado del Ejercicio 1, escribe el nuevo orden completo del roadmap (solo entre apuestas elegibles) incluyendo sellerVerificationBadges.
Ver solución
Con sellerVerificationBadges (4800) sumada a las tres apuestas elegibles originales (reviews: 2400, sellerTools: 960, recommendations: 833.33), el nuevo roadmap ordenado por riceScore sería: sellerVerificationBadges (4800) > reviews (2400) > sellerTools (960) > recommendations (833.33). Fíjate en que esta nueva apuesta tiene un riceScore (4800) menor que las dos apuestas rechazadas del backlog original (lowestPriceMatch: 7600, fasterCheckout: 6400) — y eso no importa en absoluto: lo que decide su lugar en el roadmap es su posición entre las elegibles, no una comparación directa contra apuestas que nunca calificaron para competir. Un riceScore de 4800 que sí pertenece a la estrategia vale más, para el roadmap, que un riceScore de 7600 que no pertenece — esa es, en un solo número, la tesis completa del módulo.
Ejercicio 3 — Presenta el filtro y el roadmap final al equipo fundador de Mercado. Escribe, en un párrafo, cómo presentarías las tres partes de este proyecto —el filtro, el roadmap, y la comparación contra RICE puro— a el equipo fundador de Mercado, cerrando con lo que esta guía completa les permitió construir.
Ver solución
Un ejemplo de respuesta: "Este trimestre partimos de seis apuestas candidatas. Antes de mirar cuál tenía el mejor número, les preguntamos a las seis si pertenecían al juego que decidimos jugar: descubrimiento curado y confianza en el vendedor, no precio ni conveniencia genérica. Tres pasaron esa prueba —reviews, sellerTools, recommendations—, y las secuenciamos con la misma fórmula RICE que ya usábamos, ahora aplicada solo entre ellas: reviews primero, después sellerTools, después recommendations. Las otras tres —incluidas las dos apuestas con mejor rendimiento esperado bruto de todo el backlog— quedan fuera, con una razón específica cada una, no por falta de tiempo. Este es el resultado directo de todo el trabajo de estrategia que hicimos: la visión que nos dijo hacia dónde vamos, el segmento y posicionamiento que eligieron a quién servimos primero, la diferenciación que confirmó que no competimos en paridad, el mapa competitivo que nos mostró el espacio despejado, los moats que nos dijeron qué defender, y ahora, por fin, el filtro que convierte todo eso en la lista exacta de lo que construimos este trimestre — y, con la misma claridad, en la lista de lo que decidimos no construir, aunque el número dijera lo contrario."
Resumen y siguiente paso
En este mini-proyecto reuniste el módulo completo en un solo flujo verificado: el backlog de seis apuestas de Mercado pasado por strategicFilter (tres elegibles, tres rechazadas, cada una con su razón), el roadmap final secuenciado con riceScore solo entre las elegibles (reviews > sellerTools > recommendations), y la comparación final contra lo que un ranking de RICE puro hubiera producido —encabezado por las dos apuestas que la estrategia de Mercado, con razón, rechaza—. Con esto cierras el módulo 7.
Hacia dónde sigues. Tienes ahora las siete piezas completas de esta guía: visión (módulo 2), segmento y posicionamiento (módulo 3), diferenciación (módulo 4), competencia y mercado (módulo 5), moats (módulo 6), y el filtro que baja todo eso al roadmap (este módulo). El módulo 8, el capstone final de la guía, te pide construir la estrategia de producto de Mercado de principio a fin, en un solo documento — el one-pager de estrategia completo, con toda la lógica ejecutada en Node, cerrando el arco entero de product-strategy-for-engineers-guide y conectando, por última vez, con product-thinking-for-engineers-guide: la guía que elige el juego, entregándole el resultado a la guía que lo juega.
Recursos
- Roger Martin, "Decoding the Strategy Choice Cascade" — rogermartin.medium.com/decoding-the-strategy-choice-cascade-475d40555eb1. El marco completo de Playing to Win, para releer ahora que tienes tu propia versión, ejecutada en código, de cómo una cascada de elecciones estratégicas termina en una acción concreta de roadmap. En inglés.
- Melissa Perri, Escaping the Build Trap — oreilly.com/library/view/escaping-the-build/9781491973767. El diagnóstico completo de la trampa —construir sin conexión con una estrategia real—, ahora con la herramienta exacta, en código, para evitarla en cualquier backlog futuro. En inglés.
- Marty Cagan (Silicon Valley Product Group), "Product Strategy" — svpg.com/product-strategy-overview. Cagan cierra el argumento de todo el módulo: la estrategia de producto solo tiene valor real el día que decide qué se construye y qué no — exactamente el resultado de este proyecto. En inglés.
- 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. El puente natural hacia el módulo 8: un roadmap que traza cada línea de vuelta a una meta explícita, tal como el trazado completo que construiste en este proyecto. En inglés.