Estimación y planificación

"Las estimaciones son útiles. La precisión, no tanto. Si tu estimación es exacta, sospechá de la complejidad real del problema."

Qué vas a aprender en este capítulo

Estimar software es notoriamente difícil. Este capítulo cubre técnicas que han demostrado funcionar (y por qué), cómo construir roadmaps realistas, y cómo trackear progreso de forma honesta.


2.1 ¿Por qué estimar?

📐 Fundamento

Estimar sirve para:

  • Decidir si vale la pena hacer algo (ROI vs esfuerzo).
  • Priorizar (¿hacer A primero o B?).
  • Coordinar dependencias entre equipos.
  • Comunicar a stakeholders cuándo esperar entregas.
  • Detectar early cuando algo va mal (estimación 1 día → tomamos 5 días → revisar plan).

Estimar NO sirve para:

  • Comprometerse a fechas exactas.
  • Evaluar performance de individuos.
  • Reemplazar la planificación.

El cono de incertidumbre:

Variabilidad
  16x ┤    ╲
      │     ╲
   4x ┤      ╲___
      │          ╲___
   2x ┤              ╲___
      │                  ╲___
  1x  ┤                       ╲────  ← estimación se acerca a la realidad
      └────────────────────────────────→ Tiempo
       Inicio    Análisis   Diseño   Construcción
       (mucho   (menos    (poco    (precisión real)
        unknown) unknown)  unknown)

Implicación: las estimaciones tempranas son malas y eso es inevitable. Refinarlas a medida que aprendemos.


2.2 Técnicas de estimación

📐 Fundamento

Estimación absoluta (horas):

"Esta tarea me toma 8 horas".

Problema: somos terribles estimando absoluto. Sesgos: optimismo, no contemplar problemas, comparar con quien estima rápido.

Estimación relativa (story points):

"Esto es 'mediano', similar a la tarea X que ya hicimos".

Comparar tamaños relativos es mucho más natural y preciso que estimar tiempo absoluto.

Escalas comunes:

  • Fibonacci: 1, 2, 3, 5, 8, 13, 21 (la más usada).
  • Camisetas: XS, S, M, L, XL, XXL (cualitativo).
  • Potencias de 2: 1, 2, 4, 8, 16.

¿Por qué Fibonacci? Refleja la incertidumbre creciente: la diferencia entre 1 y 2 es chica, entre 13 y 21 es grande (porque para tareas grandes ya no podés ser preciso).

Planning Poker:

1. PO presenta una historia.
2. Devs preguntan, clarifican.
3. Cada uno elige una carta (en privado): 1, 2, 3, 5, 8, 13...
4. Todos voltean al mismo tiempo.
5. Si hay disparidad: discutir POR QUÉ.
   - Quien votó 1: "es un cambio simple, una hora".
   - Quien votó 13: "ah, yo pensé en hacer también la migración de datos".
6. Re-votar hasta convergir.

Por qué funciona:

  • Anti-anchoring: no hay "el primero que dijo 5" influyendo a los demás.
  • Captura conocimiento de todo el equipo (el junior puede ver algo que el senior no).
  • La discusión revela suposiciones implícitas.

T-shirt sizing para estimación inicial:

Para algo más grande que un sprint (épica, proyecto):

XS: < 1 sprint
S: 1-2 sprints  
M: 1 mes
L: 1 trimestre
XL: 2-3 trimestres
XXL: > 3 trimestres → demasiado grande, romper en pedazos

Triple estimación (PERT):

Estimación = (Optimista + 4 × Más probable + Pesimista) / 6

Ejemplo: O=2, M=5, P=14
Estimación = (2 + 4×5 + 14) / 6 = 36/6 = 6 días

Útil para reportar a stakeholders un rango: "entre 2 y 14 días, esperamos 6".


2.3 Velocity y forecasting

📐 Fundamento

Velocity: story points completados por sprint en promedio.

Sprint 1: 18 pts
Sprint 2: 22 pts
Sprint 3: 20 pts
Sprint 4: 25 pts
Sprint 5: 21 pts

Velocity promedio: 21.2 pts/sprint

Forecast simple:

Si tenemos 200 story points en el backlog y velocity = 21:
200 / 21 ≈ 10 sprints ≈ 5 meses (sprints de 2 semanas)

Mejor: Monte Carlo simulation:

En lugar de un solo número (10 sprints), simular cientos de escenarios usando la distribución real de velocity:

import numpy as np

velocity_history = [18, 22, 20, 25, 21, 19, 24, 20]
backlog_pts = 200
n_simulations = 10000

durations = []
for _ in range(n_simulations):
    completed = 0
    sprints = 0
    while completed < backlog_pts:
        completed += np.random.choice(velocity_history)
        sprints += 1
    durations.append(sprints)

p50 = np.percentile(durations, 50)
p85 = np.percentile(durations, 85)
p95 = np.percentile(durations, 95)

print(f"50% probabilidad: {p50:.0f} sprints")
print(f"85% probabilidad: {p85:.0f} sprints")
print(f"95% probabilidad: {p95:.0f} sprints")

# Comunicar a stakeholders:
# "85% probabilidad de terminar en 11 sprints. 95% en 13."

Esto es honesto sobre la incertidumbre (rango), no engañoso (un solo número).

Anti-patrones de velocity:

  • Comparar velocity entre equipos: son números relativos, equipo A con vel=20 y equipo B con vel=40 NO significa que B sea más productivo.
  • Velocity como métrica de performance: los devs aprenden a inflar story points → métrica corrupta.
  • Compromiso por velocity media: la mitad de los sprints fallan en cumplir si comprometés la media.

2.4 Roadmap y planning a largo plazo

📐 Fundamento

Niveles de planificación:

Visión (3-5 años)        ← donde queremos estar
   ↓
Roadmap (1 año)          ← grandes objetivos por trimestre
   ↓
Release (3 meses)        ← features comprometidas
   ↓
Sprint (2 semanas)       ← qué hacemos en 10 días
   ↓
Daily (1 día)            ← qué hacemos hoy

Roadmap por temas (no por features):

Q1: ESCALABILIDAD       Q2: MONETIZACIÓN     Q3: EXPANSIÓN
- Migrar a microserv.   - Suscripciones      - Lanzar México
- Performance backend   - Pagos              - Localización
- Reducir tech debt     - Analytics         - Multi-currency

Mejor que: "Q1: implementar feature X, Y, Z" (compromisos rígidos que casi seguro cambian).

Now / Next / Later — alternativa a Gantt:

NOW (este trimestre)         NEXT (próximo trim)        LATER (futuro)
- App móvil iOS              - App móvil Android        - Apple Watch
- Pagos con tarjeta          - Pagos con BTC?           - Programa de fidelidad
- Dashboard mozos            - Dashboard cocina         - AI recomendaciones

Comunica prioridades sin comprometer fechas exactas.

Gantt charts (cuándo aún tienen sentido):

Tarea                Sem1 Sem2 Sem3 Sem4 Sem5 Sem6 Sem7 Sem8
─────────────────────────────────────────────────────────────
Diseño DB           ████
Migración esquemas       ████
Testing migración             ██
API v2                        ███████
Frontend v2                        ████████
QA                                          ████
Deploy                                            ██

Útil cuando hay dependencias rígidas (ej: deploy después de QA después de desarrollo). Limitado para software pure-agile.

Critical Path Method (CPM):

La cadena de tareas dependientes que define la duración total. Acelerar tareas fuera del critical path NO acelera el proyecto.


2.5 Tracking de progreso

📐 Fundamento

Burndown chart (clásico Scrum):

Story Points
   ↑
50 ┤●
   │ ╲
40 ┤  ●  ● ← real (fuera del ideal)
   │   ╲╲╱
30 ┤    ●
   │     ╲
20 ┤      ╲● ← ideal
   │       ╲
10 ┤        ●
   │         ╲
 0 └──────────●──→ Días del sprint
   D1   D5    D10

Muestra cuánto trabajo queda. Si la curva real se aplana → estamos atrasados.

Burnup chart:

Total Story Points
   ↑
60 ┤            ──── ← scope total (puede subir si se agregan items)
50 ┤          ╱
40 ┤        ╱
30 ┤      ╱   ← completado
20 ┤    ╱
10 ┤  ╱
 0 └────→ Días

Mejor que burndown porque muestra scope creep (cuando crece el alcance).

Cumulative Flow Diagram (CFD) — para Kanban:

Cantidad de tareas
   ↑
30 ┤████████ Done
20 ┤████████████ In Progress
10 ┤██████████████ Backlog
 0 └────────────────→ Tiempo

Si "In Progress" crece → cuello de botella. Si "Backlog" crece más rápido que "Done" → demanda > capacidad.

Métricas que importan reportar:

  • Predictability: ¿cumplimos los compromisos del sprint? (% de stories completadas vs comprometidas).
  • Cycle time: tiempo desde "in progress" hasta "done".
  • Defects escaped: bugs encontrados en producción.
  • Customer satisfaction: NPS, CSAT.

Métricas a EVITAR reportar:

  • Lines of code: premia escribir más, no mejor.
  • Hours worked: premia presentismo, no resultado.
  • Velocity per individual: corrompe el equipo.

2.6 Ejercicios

✏️ Ejercicio 2.1 — Planning Poker simulado

Tu equipo está estimando estas historias de La Esquina Cloud. Asignales story points (Fibonacci) y justificá:

a. "Como mozo, quiero marcar un pedido como cancelado para no procesarlo."

b. "Como dueño, quiero un dashboard con ventas mensuales por local con filtros, exportable a Excel y PDF."

c. "Como cliente, quiero recibir notificaciones push cuando mi pedido cambia de estado."

d. "Como sistema, quiero migrar la base de datos de PostgreSQL 14 a 16 sin downtime."


2.7 Para profindizar

2.X Errores comunes

⚠️ Trampa común

Dar una estimación como un número exacto. "Lo entrego en 14 días" no es una estimación, es una promesa frágil. Toda estimación es una distribución de probabilidad: tiene un mínimo razonable, un valor típico y un peor caso. Reducirla a un número fijo destruye la información sobre incertidumbre.

Tip: dá un rango con confianza ("entre 12 y 21 días, 90 % de probabilidad"). Si el cliente exige un número, dale el percentil 80 (no el 50): la mitad de los proyectos se atrasan, raramente se adelantan.

⚠️ Trampa común

Usar la velocity de un sprint para extrapolar 6 meses. Velocity = puntos completados por sprint, en un equipo estable, con scope estable. Cualquier cambio (rotación, vacaciones, scope nuevo) la invalida. Sumar 6 sprints × velocity para prometer una fecha es proyectar ruido como si fuera señal.

Tip: mostrá el dato como una banda de incertidumbre. Monte Carlo sobre los últimos 8-10 sprints da fechas con probabilidad asociada, no una fecha falsa de precisa.


Definiciones nuevas: estimación absoluta vs relativa, story point, Fibonacci, Planning Poker, T-shirt sizing, PERT, velocity, Monte Carlo simulation, roadmap, Now/Next/Later, Gantt chart, critical path, burndown, burnup, CFD, scope creep.