Módulo 2: Slis Slos And The Error Budget
8. Proyecto: `SLO.md` de Andes Cargo
Descripción
Siete lecciones construyeron la evidencia; esta la convierte en decisión. Este proyecto final del módulo escribe SLO.md, el documento que RELIABILITY-CHARTER.md dejó explícitamente abierto en el Módulo 1: "¿Qué SLI y SLO tienen sentido para process-shipment-manifest, con evidencia?". La respuesta ya no es una promesa vacía ni un número elegido "porque suena responsable" — es el SLI definido por escrito en la lección 3, el SLO elegido entre tres escenarios corridos con datos reales en la lección 5, y el comportamiento de burn rate de las lecciones 6 y 7, reunidos en un solo documento con la misma disciplina de ADR que RELIABILITY-CHARTER.md ya estableció.
Conexión con el módulo
Este es el entregable que el resto de esta guía mide y cita, sin volver a discutirlo: el Módulo 3 construye el pipeline de telemetría real que reemplaza el dataset fijo de la lección 4 por datos en vivo de CloudWatch/Prometheus, alimentando exactamente el SLI que este documento define. El Módulo 4 alerta sobre burn rate contra el SLO exacto de este documento. El Módulo 6 mide el incidente Claude Code real contra este mismo SLO. El Módulo 7 lo cita directamente en el postmortem. El Módulo 8 corre un incidente sintético nuevo contra el mismo presupuesto de 43,2 minutos que este documento fija aquí.
Paso 1 — Por qué este documento sí puede elegir un SLO, a diferencia de RELIABILITY-CHARTER.md
RELIABILITY-CHARTER.md rechazó, a propósito, elegir un SLO en el Módulo 1 — la evidencia todavía no existía. Ese mismo documento fue explícito sobre qué haría falta para tomar esa decisión con criterio: las cuatro señales doradas (lección 2 de este módulo) y un dataset real (lección 4). Ambas cosas ya existen. Además, este documento tiene algo que RELIABILITY-CHARTER.md nunca tuvo: tres corridas reales de la calculadora, sobre el mismo tráfico, contra tres SLOs distintos (lección 5), que muestran con números —no con intuición— cuál de los tres es defendible. Elegir un SLO ahora, con esa evidencia detrás, es exactamente lo contrario del error que RELIABILITY-CHARTER.md evitó — es la decisión que toda esa evidencia estaba preparando.
Paso 2 — El documento completo
En la raíz de andes-cargo-infra/, crea SLO.md:
# SLO.md — process-shipment-manifest Reliability Target
**Status:** Accepted · **Date:** this module's close · **Supersedes:** none
**Governs:** Modules 3 through 8 of `sre-and-incident-response-guide`
**Source:** Module 2, lessons 2-7 (the four golden signals, the SLI definition, three calculator
runs across a real 30-day dataset and a synthetic bad week)
## SLI
**Definition:** the proportion of valid events that were good, applied to `process-shipment-manifest`
(Module 2, lesson 3, citing Google's *Art of SLOs*).
- **Valid event:** any invocation triggered by a real S3 upload of a shipment manifest to
`andes-cargo-shipment-docs`. Manual test invocations (console/CLI, synthetic payloads used only to
verify a deployment) are excluded from the denominator entirely — they do not represent real
customer traffic.
- **Good event:** a valid invocation that completes without an unhandled exception, within the
10-second `Timeout`, and writes a correct record to `Shipments`. Explicitly counted as **not good**
(bad, within valid events, never excluded from the denominator): an invocation throttled by
`ReservedConcurrentExecutions: 5`, an invocation that exceeds the 10-second timeout, and an
invocation that exhausts its two automatic retries and is silently dropped — the three risks
Module 1, lesson 4 identified and left unresolved.
```text
SLI = good_events / valid_events
```
## SLO
**99.9% monthly**, measured over a 30-day rolling window.
**Why not 99%:** Module 2, lesson 5 ran the calculator's real 30-day dataset (SLI 99.9098%) against
a 99% target and found 393.03 minutes of budget remaining — 90% of the monthly budget untouched. A
99% target would never have flagged the two-day degradation of days 17-18 as anything but routine; it
sets a bar this system would clear even during a real incident, which defeats the purpose of having a
target at all.
**Why not 99.99%:** the same real dataset, run against 99.99%, produced a budget deficit of -34.65
minutes — a system with no architectural changes and no unusual failure mode would have "failed" its
SLO nearly every month. `RELIABILITY-CHARTER.md` (Module 1, lesson 8, Decision point 2) already
rejected chasing 99.99%+ for a system that is "not a payments system or a life-support system" — an
asynchronous manifest processor, where a few extra minutes of delayed processing carries no real cost
to the business. Module 2, lesson 3 of `terraform-and-iac-guide`'s sibling reasoning (Embracing Risk,
Google SRE Book, Chapter 3) applies directly: each additional nine can cost 100x more than the last,
and nothing about this system's business need justifies that cost.
**Why 99.9%:** it is the only one of the three scenarios tested where the real 30-day dataset landed
close to the line without crossing it — 90.2% of budget consumed, 4.23 minutes remaining. This is a
target the system can meet under real, measured conditions, but not so loose that a genuine
degradation (like the days 17-18 incident, or the synthetic bad week of Module 2, lesson 7) goes
unnoticed. A number that is barely met is a number that still means something.
## Error budget
- **43.2 minutes per 30-day window** — `(1 - 0.999) × 43200 minutes`.
- **Measured against the real 30-day traffic dataset (Module 2, lesson 4):** 38.97 minutes consumed
(90.2%), 4.23 minutes remaining. This is the reference measurement this document commits to — not a
live number (Module 3 builds the real telemetry pipeline that keeps it current), but the evidence
this SLO was chosen with, not guessed at.
- **Burn rate context (Module 2, lessons 6-7):** the two-day incident inside that same 30-day window
reached a daily burn rate of up to 13.27x, and the synthetic bad week of lesson 7 reached 43.41x
sustained over seven days — both far above the 1x sustainable rate, both examples of exactly the
kind of event this budget exists to quantify, not prevent.
## Alternatives considered
**99% (two nines).** Rejected: Module 2, lesson 5 showed the real dataset clears this target with 90%
of its budget untouched even during a real two-day degradation — a target too loose to mean anything
operationally for this system.
**99.99% (four nines).** Rejected: the same real dataset breaches this target by -34.65 minutes with
no unusual failure mode present — a target this system's current architecture cannot sustain, and one
`RELIABILITY-CHARTER.md` already ruled out on business grounds (Decision, point 2).
**No SLO chosen yet, deferring further (matching Module 1's approach).** Rejected: `RELIABILITY-
CHARTER.md` deferred choosing an SLO specifically until the four golden signals (Module 2, lesson 2)
and a real dataset (Module 2, lesson 4) existed. Both now exist. Deferring further would repeat the
same "100% because it sounds responsible" mistake Module 1, lesson 3 already named, this time as "no
number because it feels safer than committing to one."
## Consequences
Every module from here forward measures against this document, not around it: Module 3 builds the
real telemetry pipeline that replaces the fixed 30-day dataset with live CloudWatch/Prometheus data
feeding the same SLI definition. Module 4 alerts on burn rate against this exact SLO. Module 6
measures the real Claude Code incident against this SLO, retroactively. Module 7's postmortem cites
this document's numbers directly. Module 8's capstone runs a new synthetic incident through the same
machine, against the same 43.2-minute budget defined here.
Paso 3 — Verificando el documento
wc -l SLO.md
grep -c '^## ' SLO.md
grep -c 'Rejected' SLO.md
Qué esperar (literal — el contenido lo escribiste tú, la forma es determinista):
88
5
3
Ochenta y ocho líneas, cinco secciones (SLI, SLO, Error budget, Alternatives considered, Consequences), y tres alternativas explícitamente rechazadas —99%, 99,99%, y "seguir sin decidir"—, cada una con su razón, ninguna simplemente omitida sin explicación.
Cómo leer este documento, seis meses después
La misma prueba que RELIABILITY-CHARTER.md ya superó en el Módulo 1: frente a este documento, sin preguntarle a nadie, un lector nuevo debería poder contestar cuatro preguntas. ¿Qué cuenta como "bueno" para este sistema? (sección SLI, con las tres exclusiones explícitas —timeout, saturación, reintentos agotados— nombradas, no escondidas). ¿Por qué 99,9% y no otro número? (sección SLO, con los tres escenarios de la lección 5 citados con sus cifras exactas, no con una opinión). ¿Cuánto margen hay, de verdad, hoy? (sección Error budget, 4,23 de 43,2 minutos —un margen ajustado, declarado como tal, no maquillado). ¿Qué otras opciones se consideraron y por qué se descartaron? (Alternatives considered, tres entradas, cada una con evidencia). Si alguna de esas cuatro preguntas exige releer una lección completa de este módulo, el documento no cumplió su función — el mismo estándar que RELIABILITY-CHARTER.md ya fijó.
El cierre del Módulo 2
Con SLO.md escrito, este módulo entrega exactamente lo que prometió en la lección 1: no un cálculo de una sola vez como el del Módulo 1, sino una calculadora real y reutilizable (scripts/error_budget_calculator.py, construida en la lección 4 y extendida en la 6), corrida sobre datos reales dos veces (lecciones 4-6 y lección 7), y la decisión formal —con evidencia, no con una corazonada— que cierra la fila Open que RELIABILITY-CHARTER.md dejó pendiente. Entras al Módulo 3 con un SLI definido, un SLO elegido con datos, y un presupuesto de error medido en minutos exactos — la base sobre la que el resto de esta guía construye, sin volver a discutir ninguna de estas tres cosas.
Errores comunes
Tratar el 4,23 de "Error budget" como si fuera un número que se actualiza solo (de esperar automatización que todavía no existe). Qué pasa: alguien asume que, a partir de este documento, el presupuesto restante se recalcula automáticamente cada vez que corre tráfico real. Cómo detectarlo: si esperas que SLO.md cambie sin que nadie lo edite. Cómo corregirlo: el documento es explícito en que ese 4,23 es una medición de referencia, tomada sobre el dataset fijo de la lección 4 — no un valor en vivo. El Módulo 3 de esta guía es, específicamente, el que construye el pipeline de telemetría real que alimenta la misma fórmula con datos que sí cambian con el tiempo; hasta entonces, este número es la evidencia con la que se tomó la decisión, no un contador activo.
Copiar la justificación de "por qué 99,9%" sin verificar que las cifras coinciden con las que tú mismo obtuviste en la lección 5 (de copiar sin correr). Qué pasa: alguien pega el documento de esta lección sin haber corrido realmente la calculadora de las lecciones 4-7, confiando en que los números "seguramente son correctos". Cómo detectarlo: si no puedes reproducir, corriendo tu propia copia de scripts/error_budget_calculator.py, el 90,2% de presupuesto consumido citado en este documento. Cómo corregirlo: cada cifra de SLO.md proviene de una corrida real de un script que tú ya escribiste y ejecutaste en las lecciones anteriores de este módulo — antes de dar por bueno este documento, confirma que tu propia calculadora produce, dígito por dígito, los mismos números que aparecen aquí citados.
Agregar una cuarta alternativa considerada "para que se vea más completo" sin evidencia real detrás (el mismo error de la lección 8 del Módulo 1, reaparecido aquí). Qué pasa: alguien, incómodo con solo tres alternativas, agrega una cuarta (por ejemplo, "SLO por hora en vez de mensual") sin haberla corrido con la calculadora. Cómo detectarlo: si alguna entrada de "Alternatives considered" en tu versión de SLO.md no cita ninguna cifra específica de una lección de este módulo. Cómo corregirlo: la sección Alternatives considered de RELIABILITY-CHARTER.md ya estableció el estándar — cada alternativa rechazada necesita su propia evidencia, no solo su propio párrafo. Si quieres explorar una cuarta alternativa real, la forma correcta es correr la calculadora con ese escenario primero, y solo entonces documentar el resultado real, sea cual sea.
Ejercicios
Ejercicio 1 — Verifica el documento completo contra tu propia ejecución de la calculadora. Corre scripts/error_budget_calculator.py con SLO=0.999 sobre TRAFFIC_30_DAYS y confirma que produce exactamente 90,2% de presupuesto consumido y 4,23 minutos restantes, los mismos números citados en la sección "Error budget" de este documento.
Ver solución
Corriendo budget_report(TRAFFIC_30_DAYS) (SLO por defecto, 0,999) se obtiene: Consumido en el periodo: 38.97 minutos (90.2% del presupuesto) y Presupuesto restante: 4.23 minutos — coincide exactamente con SLO.md. Este ejercicio no es una formalidad: es la verificación de que el documento de portafolio que acabas de escribir es trazable hasta un script ejecutable, no una afirmación sin respaldo. Cualquier persona que audite este documento puede correr el mismo script y llegar exactamente al mismo lugar.
Ejercicio 2 — Defiende la sección SLO frente a una objeción real. Un entrevistador técnico pregunta: "si el sistema ya está usando el 90% de su presupuesto con tráfico normal, ¿no deberían simplemente haber elegido un SLO más laxo, como 99%, para tener más margen de maniobra?". ¿Cómo respondes, usando el propio documento?
Ver solución
Una respuesta completa: "La Sección 'Por qué no 99%' de este documento ya contesta esa pregunta con evidencia, no con preferencia: a 99%, el mismo tráfico real que aquí consume el 90,2% del presupuesto a 99,9% habría consumido apenas el 9% a 99%, dejando 393 minutos sin tocar incluso durante el incidente real de los días 17-18. Un SLO tan laxo no habría distinguido ese incidente de un mes perfectamente sano — el número dejaría de significar algo, exactamente el problema que este documento evita a propósito, citando la lección 5 del Módulo 2. Elegir un SLO 'con más margen' suena prudente, pero en los hechos elige no medir nada: el margen que sobra es margen que nunca se usa para detectar un problema real. Preferimos un SLO ajustado, que el sistema apenas cumple, porque es el único que da información útil cuando algo sale mal."
Ejercicio 3 — Explica por qué la sección "Alternatives considered" de este documento incluye "no elegir SLO todavía" como una opción explícitamente rechazada, en vez de simplemente no mencionarla. ¿Qué gana el documento al nombrar y rechazar esa opción, en vez de solo omitirla?
Ver solución
Nombrar y rechazar explícitamente "seguir sin decidir" cierra una puerta que, de otro modo, quedaría abierta por omisión: sin esa entrada, alguien podría razonar que el equipo simplemente no consideró la opción de esperar más evidencia antes de comprometerse con un número. Al nombrarla y rechazarla con una razón concreta —la misma evidencia que RELIABILITY-CHARTER.md pidió (cuatro señales doradas, un dataset real) ya existe, así que seguir esperando no añadiría rigor, solo retrasaría una decisión ya lista para tomarse—, el documento demuestra que la decisión de comprometerse con 99,9% ahora fue deliberada, no apresurada ni evitada por descuido. Es el mismo patrón que RELIABILITY-CHARTER.md usó al rechazar explícitamente "elegir un SLO placeholder ahora" en el Módulo 1 — declarar la opción no tomada, con su razón, en vez de dejarla como un hueco silencioso que alguien podría cuestionar después.
Resumen y siguiente paso
En este proyecto final del módulo escribiste SLO.md: el SLI de process-shipment-manifest definido con precisión (bueno vs. válido, con los tres riesgos del Módulo 1 explícitamente incluidos como fallas, nunca excluidos por conveniencia), el SLO elegido —99,9% mensual— con la evidencia exacta de los tres escenarios de la lección 5, y el presupuesto de error —43,2 minutos, con solo 4,23 restantes sobre el tráfico real medido— con el contexto de burn rate de las lecciones 6 y 7. Verificaste el documento con la misma disciplina determinista de todo este ecosistema: 88 líneas, 5 secciones, 3 alternativas rechazadas con evidencia, ninguna decisión sin justificación.
Antes de cerrar este módulo deberías poder: recitar la definición completa de SLI de este documento sin mirarlo; explicar, con cifras exactas, por qué 99,9% y no 99% ni 99,99%; y reproducir, corriendo tu propia calculadora, cada número que este documento cita.
Con esto, el Módulo 2 de sre-and-incident-response-guide queda completo: la matemática real de SRE, corrida de verdad sobre datos fijos y committeados, con una herramienta reutilizable que el resto de esta guía usa sin volver a construir. El Módulo 3 toma exactamente el SLI que este documento define y lo alimenta, por primera vez, con datos que no vienen de un dataset fijo — invocaciones reales del Lambda heredado, leídas con awslocal cloudwatch get-metric-statistics.
Recursos
- Este módulo, lecciones 2 a 7 — la fuente directa de cada cifra y cada decisión de este documento.
- Este mismo repositorio, Módulo 1, lección 8 (
08-project-andes-cargos-reliability-charter.md) —RELIABILITY-CHARTER.md, el documento que dejó la pregunta queSLO.mdcontesta. - Google — The Art of SLOs (Participant Handbook) — la fórmula de SLI que la sección SLI de este documento cita.
- Google SRE Workbook — Implementing SLOs — la fórmula de error budget que la sección Error budget de este documento aplica.
finops-and-cost-guardrails-guide, Módulo 1, lección 8 ycloud-security-and-guardrails-guide, Módulo 1, lección 8 — el mismo formato de ADR de portafolio queSLO.mdsigue, ya usado dos veces en este ecosistema.