Módulo 2: Mental Models para AI Code
Trust Calibration por Tipo de Tarea
Trust Calibration por Tipo de Tarea
Descripción de la cápsula
Ya sabes cómo supervisar (Managing an Intern) y cuándo pausar (Circuit Breaker). Ahora necesitas la herramienta más accionable de las tres: cuánto confiar. Trust Calibration convierte "creo que está bien" en "para este tipo de tarea, mi confianza es del 40%, así que reviso lógica y edge cases." Es la diferencia entre intuición y proceso.
En el módulo 1 viste una tabla preliminar de confianza por tipo de tarea. Esta cápsula la expande significativamente: vas a construir una tabla detallada con 15 tipos de tarea, entender los factores que suben y bajan tu confianza, y aprender a actualizar tu calibración con experiencia. Trust Calibration es el modelo que puedes aplicar literalmente mañana en tu trabajo.
La clave: Trust Calibration no es un número exacto. Es un rango que guía tu comportamiento. "70% de confianza" no significa que 7 de cada 10 veces el código es correcto. Significa que tu nivel de revisión corresponde a una tarea de riesgo moderado donde una revisión enfocada es suficiente.
Trust Calibration como Proceso Estructurado
No es intuición — es proceso
La mayoría de developers calibra por intuición: "se ve bien" o "algo no me gusta". La intuición tiene dos problemas:
Problema 1: La intuición es inconsistente
├── Lunes por la mañana (descansado): "Voy a revisar todo"
├── Viernes a las 6 PM (cansado): "Se ve bien, acepto"
└── El riesgo del código no cambió. Tu calibración sí.
Problema 2: La intuición no es comunicable
├── "¿Por qué aceptaste este código sin revisión?"
├── "No sé, se veía bien"
└── No puedes enseñar ni defender "se veía bien"
Trust Calibration reemplaza intuición con proceso:
Proceso de Trust Calibration:
1. Identificar el tipo de tarea
2. Consultar tu tabla de confianza base
3. Ajustar por factores contextuales
4. Definir profundidad de revisión según resultado
5. Documentar y actualizar con experiencia
El modelo mental
Piensa en Trust Calibration como un termómetro de confianza:
100% ─── Confianza total (no existe para AI code)
90% ─── Revisión visual (boilerplate, formateo)
80% ─── Revisión rápida (config, docs)
70% ─── Revisión enfocada (CRUD, utilidades)
60% ─── Revisión detallada (lógica media)
50% ─── Revisión cuidadosa (tests, queries)
40% ─── Revisión exhaustiva (lógica de negocio)
30% ─── Revisión línea por línea (data pipelines)
20% ─── Desconfianza activa (regex, concurrencia)
10% ─── Verificación contra documentación (auth, crypto)
0% ─── No confíes, escribe tú (no existe tampoco)
Tu posición en el termómetro determina tu comportamiento: cuánto tiempo dedicas, qué tan profundo revisas, y qué herramientas usas para verificar.
La Tabla de Trust Calibration
Tabla completa: 15 tipos de tarea
| # | Tipo de tarea | Confianza base | Profundidad de revisión | Qué verificar |
|---|---|---|---|---|
| 1 | README / documentación | 85-90% | Visual rápida | Que la información sea correcta y no engañosa |
| 2 | Boilerplate (setup, config inicial) | 80-90% | Visual rápida | Versiones de dependencias, paths correctos |
| 3 | Dockerfiles / CI config | 75-85% | Rápida | Imagen base, secrets no hardcoded, stages |
| 4 | Modelos de datos (Pydantic, ORM) | 70-80% | Enfocada | Campos correctos, tipos apropiados, validaciones |
| 5 | CRUD endpoints | 60-70% | Enfocada | Validaciones, error handling, status codes |
| 6 | Funciones de utilidad | 60-70% | Enfocada | Edge cases, naming, tipos de retorno |
| 7 | Tests unitarios | 50-60% | Detallada | Que testen lo correcto, no solo que pasen |
| 8 | Queries SQL / ORM | 40-55% | Detallada | SQL injection, N+1, lógica del query, índices |
| 9 | Error handling / logging | 50-60% | Detallada | Que no exponga info sensible, que capture lo necesario |
| 10 | Lógica de negocio | 25-40% | Exhaustiva | Que haga lo que el negocio necesita, valores correctos |
| 11 | Integraciones externas (APIs) | 30-45% | Exhaustiva | API correcta, manejo de errores, retry logic, timeouts |
| 12 | Data pipelines / ETL | 25-40% | Exhaustiva | Transformaciones correctas, manejo de datos null/inválidos |
| 13 | Regex patterns | 15-25% | Línea por línea | Probar con inputs edge case, false positives/negatives |
| 14 | Auth / Security / Crypto | 10-20% | Línea por línea + docs | Contra documentación oficial, cada decisión de seguridad |
| 15 | Procesamiento financiero | 10-20% | Línea por línea + tests | Cada cálculo, precision (Decimal), compliance |
Cómo leer la tabla
Confianza 80-90%: "Probablemente está bien"
→ Revisión visual de 1-3 minutos
→ Si algo salta a la vista, profundiza
→ Si no, acepta
Confianza 60-70%: "Está bien si las partes clave están bien"
→ Revisión de 5-10 minutos enfocada en lógica y edge cases
→ No cada línea, pero sí las funciones principales
Confianza 40-55%: "Necesito verificar"
→ Revisión de 10-20 minutos
→ Verifica lógica, prueba con inputs edge case
→ Compara contra documentación si aplica
Confianza 10-30%: "Asumo que hay problemas hasta probar lo contrario"
→ Revisión de 20-40 minutos
→ Lee cada línea, verifica contra docs oficiales
→ Escribe tests para cada escenario
→ Pregúntate "¿cómo podría fallar esto?"
Factores que Ajustan tu Calibración
Factores que AUMENTAN confianza
Tu confianza base sube cuando estas condiciones están presentes:
+10-15%: Tests existentes que cubren el escenario
→ Si hay tests que verifican la lógica, tu revisión
puede ser menos exhaustiva. Los tests hacen parte
del trabajo de verificación.
+5-10%: Dominio que conoces bien
→ Si conoces el dominio, detectas errores más rápido.
Tu revisión rápida es más efectiva que la revisión
exhaustiva de alguien que no conoce el dominio.
+5-10%: Patrón estándar bien documentado
→ Si el código sigue un patrón que has visto 100 veces
(ej: CRUD FastAPI estándar), la probabilidad de error
es menor.
+5%: Código corto y simple (< 30 líneas, flujo lineal)
→ Menos líneas = menos superficie de error.
Pero no confundas corto con seguro (3 líneas de
SQL injection son peores que 300 de CRUD).
+5-10%: Claude Code tiene buen track record en esta tarea
→ Si las últimas 5 veces que pediste CRUD endpoints
el resultado fue correcto, tu calibración sube.
Factores que DISMINUYEN confianza
Tu confianza base baja cuando estas condiciones están presentes:
-10-20%: No hay tests
→ Sin tests, eres la única línea de defensa.
Tu revisión debe ser más exhaustiva.
-10-15%: Dominio que no conoces
→ Si no conoces el dominio, errores sutiles pueden
pasar desapercibidos. Una función de cálculo de
impuestos puede "verse bien" pero tener los
porcentajes equivocados.
-10-15%: Código con state mutable o side effects
→ Side effects (modifica DB, envía emails, llama APIs)
son difíciles de verificar visualmente. Necesitas
ejecutar o escribir tests.
-5-10%: Prompt fue vago o ambiguo
→ Si tu prompt no fue específico, Claude Code tuvo
que "adivinar" tu intención. Más probabilidad de
que adivinó mal.
-10-20%: Seguridad o compliance involucrado
→ Cualquier cosa que toque auth, encryption, PII,
o regulaciones requiere desconfianza activa.
-5-10%: Código complejo (múltiples branches, async, concurrencia)
→ Complejidad alta = más superficie de error.
AI es especialmente impredecible con concurrencia.
-10-15%: Integración con API que cambió recientemente
→ Claude Code puede generar código para versiones
anteriores de una API. Si la API cambió, el código
puede usar endpoints que ya no existen.
Ejemplo: Ajustando calibración
Tarea: Generar un endpoint CRUD para productos
Confianza base (tabla): 65%
Ajustes:
+10%: Conozco bien FastAPI (dominio familiar)
+5%: Es un patrón estándar (CRUD simple)
-10%: No hay tests todavía
-5%: Mi prompt fue genérico ("genera CRUD de productos")
Confianza ajustada: 65 + 10 + 5 - 10 - 5 = 65%
→ Se mantuvo similar. Revisión enfocada de 5-8 minutos.
→ Verificar: validaciones, error handling, status codes.
Tarea: Generar middleware de rate limiting
Confianza base (tabla): 35% (lógica de negocio + seguridad)
Ajustes:
-15%: No conozco bien rate limiting algorithms
-10%: No hay tests
-10%: Tiene implicaciones de seguridad (DoS protection)
+5%: Código relativamente corto
Confianza ajustada: 35 - 15 - 10 - 10 + 5 = 5%
→ Muy baja. Revisar cada línea.
→ Verificar contra documentación de rate limiting.
→ Escribir tests antes de aceptar.
→ Considerar usar una librería probada en vez de custom.
Trust Debt: Cuando No Calibras
Qué es Trust Debt
Trust Debt es el concepto de que cuando under-calibras (confías de más), los problemas se acumulan silenciosamente, como technical debt. No ves el costo inmediatamente, pero se manifiesta eventualmente.
Trust Debt en acción:
Semana 1: Aceptas endpoint de búsqueda sin revisar queries
→ Confianza: "70% — es CRUD"
→ Realidad: queries sin parameterizar (SQL injection)
Semana 2: Aceptas endpoint de filtros sin revisar
→ Se basa en el endpoint de semana 1
→ Misma vulnerabilidad, ahora en 2 endpoints
Semana 3: Aceptas feature de "búsqueda avanzada"
→ Se basa en los 2 endpoints anteriores
→ Ahora hay 3 endpoints con SQL injection
Semana 6: Auditoría de seguridad
→ Encuentran SQL injection en 3 endpoints
→ El fix requiere cambiar 3 archivos + 2 de tests
→ 3 días de trabajo + review + QA
→ El costo de "no revisar queries" se acumuló
Cómo evitar Trust Debt
1. Calibra en el momento, no "después"
→ "Lo reviso mañana" = Trust Debt
→ Revisa en el checkpoint o documenta que falta revisión
2. No heredes calibración de otros
→ Si un compañero dice "esto está bien", verifica tú
→ Tu calibración es personal
3. Actualiza tu tabla con experiencia
→ Si descubres que Claude Code consistentemente genera
queries sin parameterizar, baja tu confianza en
"Queries SQL" de 45% a 30%
4. Paga Trust Debt periódicamente
→ Cada semana, dedica 30 minutos a revisar código AI
que aceptaste rápido durante la semana
→ Busca los patrones que tu calibración no cubrió
Actualizando tu Calibración
Track record: cómo mejorar tu tabla
Tu tabla de calibración no es estática. Se actualiza basándose en tu experiencia:
Proceso de actualización:
1. Genera código con Claude Code
2. Aplica tu calibración actual
3. Revisa según el nivel de confianza
4. ¿Encontraste problemas que tu calibración no predijo?
Si SÍ encontraste problemas inesperados:
→ Baja tu confianza base para ese tipo de tarea
→ Agrega el tipo de problema a "qué verificar"
→ Ejemplo: "CRUD siempre me salió bien, pero hoy encontré
que no manejaba soft delete. Bajo de 70% a 65% y agrego
'verificar delete behavior' a mi checklist"
Si NO encontraste problemas:
→ Mantén tu calibración (no subas prematuramente)
→ Después de 5-10 experiences sin problemas, sube 5%
→ Ejemplo: "Las últimas 8 veces que generé modelos Pydantic,
todo estuvo correcto. Subo de 75% a 80%"
Registro de calibración
Lleva un registro simple para rastrear tu calibración:
Fecha | Tipo de tarea | Confianza usada | Problemas encontrados | Ajuste
------|---------------|-----------------|----------------------|-------
03/10 | CRUD endpoint | 70% | Faltaba validación de email | -5%
03/11 | Auth JWT | 15% | Token no expiraba | Mantener 15%
03/12 | Modelo Pydantic | 80% | Ninguno | Mantener 80%
03/13 | SQL query | 45% | N+1 en join | -5%
03/14 | Dockerfile | 85% | Ninguno | Mantener 85%
Después de 20-30 entries, tu tabla de calibración refleja tu experiencia real con Claude Code, no valores teóricos.
Trust Calibration en Acción
Ejemplo completo: Calibrando un módulo nuevo
Le pides a Claude Code que genere un módulo completo de gestión de suscripciones. Genera 4 archivos. Calibras cada uno:
Archivo 1: models.py
from pydantic import BaseModel, Field
from typing import Optional
from datetime import datetime
from enum import Enum
from decimal import Decimal
class SubscriptionPlan(str, Enum):
FREE = "free"
BASIC = "basic"
PRO = "pro"
ENTERPRISE = "enterprise"
class PlanPricing(BaseModel):
plan: SubscriptionPlan
monthly_price: Decimal
annual_price: Decimal
max_users: int
features: list[str]
class SubscriptionCreate(BaseModel):
plan: SubscriptionPlan
billing_cycle: str = Field(..., pattern="^(monthly|annual)$")
payment_method_id: str
class Subscription(BaseModel):
id: str
user_id: str
plan: SubscriptionPlan
billing_cycle: str
status: str = "active"
current_period_start: datetime
current_period_end: datetime
created_at: datetime
Calibración de models.py:
├── Tipo: Modelos de datos → Confianza base: 75%
├── Ajustes:
│ ├── +5%: Conozco bien Pydantic
│ ├── +5%: Patrón estándar
│ └── Sin ajustes negativos
├── Confianza final: 85%
├── Profundidad: Revisión rápida (2-3 min)
└── Qué verifico:
├── ✅ Usa Enum para plan → Correcto
├── ✅ Usa Decimal para precios → Correcto
├── ✅ billing_cycle validado con regex → Correcto
├── ✅ Campos razonables para suscripción
└── → PASS
Archivo 2: pricing_service.py
from decimal import Decimal
from models import SubscriptionPlan, PlanPricing
PRICING = {
SubscriptionPlan.FREE: PlanPricing(
plan=SubscriptionPlan.FREE,
monthly_price=Decimal("0.00"),
annual_price=Decimal("0.00"),
max_users=1,
features=["basic_access"],
),
SubscriptionPlan.BASIC: PlanPricing(
plan=SubscriptionPlan.BASIC,
monthly_price=Decimal("9.99"),
annual_price=Decimal("99.00"),
max_users=5,
features=["basic_access", "email_support", "api_access"],
),
SubscriptionPlan.PRO: PlanPricing(
plan=SubscriptionPlan.PRO,
monthly_price=Decimal("29.99"),
annual_price=Decimal("299.00"),
max_users=25,
features=["basic_access", "email_support", "api_access",
"priority_support", "advanced_analytics"],
),
SubscriptionPlan.ENTERPRISE: PlanPricing(
plan=SubscriptionPlan.ENTERPRISE,
monthly_price=Decimal("99.99"),
annual_price=Decimal("999.00"),
max_users=100,
features=["basic_access", "email_support", "api_access",
"priority_support", "advanced_analytics",
"custom_integrations", "sla"],
),
}
def get_price(plan: SubscriptionPlan, billing_cycle: str) -> Decimal:
pricing = PRICING[plan]
if billing_cycle == "annual":
return pricing.annual_price
return pricing.monthly_price
def calculate_proration(
old_plan: SubscriptionPlan,
new_plan: SubscriptionPlan,
days_remaining: int,
billing_cycle: str,
) -> Decimal:
old_daily = get_price(old_plan, billing_cycle) / Decimal("30")
new_daily = get_price(new_plan, billing_cycle) / Decimal("30")
difference = new_daily - old_daily
return (difference * Decimal(str(days_remaining))).quantize(Decimal("0.01"))
Calibración de pricing_service.py:
├── Tipo: Lógica de negocio financiera → Confianza base: 25%
├── Ajustes:
│ ├── -10%: Los precios son inventados (no los de MI negocio)
│ ├── -5%: Cálculos de prorrateo son complejos
│ ├── +5%: Usa Decimal correctamente
│ └── -10%: No hay tests
├── Confianza final: 5%
├── Profundidad: Revisión línea por línea (15-20 min)
└── Qué verifico:
├── ⚠️ Precios son placeholder — DEBO reemplazar con los reales
├── ⚠️ Prorrateo asume 30 días por mes (no correcto para todos los meses)
├── ⚠️ ¿Qué pasa con downgrade? difference sería negativa → ¿refund?
├── ⚠️ features son strings — deberían ser Enum para validación
├── ⚠️ No maneja el caso de annual billing con prorrateo
│ (¿divide entre 30 o entre 365?)
└── → NEEDS EDIT — los cálculos financieros necesitan corrección
Archivo 3: subscription_service.py
from datetime import datetime, timedelta
from typing import Optional
from models import Subscription, SubscriptionCreate, SubscriptionPlan
from pricing_service import get_price, calculate_proration
import uuid
subscriptions_db: dict = {}
class SubscriptionService:
def create(self, user_id: str, data: SubscriptionCreate) -> Subscription:
if any(
s.user_id == user_id and s.status == "active"
for s in subscriptions_db.values()
):
raise ValueError("User already has an active subscription")
now = datetime.utcnow()
period_days = 365 if data.billing_cycle == "annual" else 30
sub = Subscription(
id=str(uuid.uuid4()),
user_id=user_id,
plan=data.plan,
billing_cycle=data.billing_cycle,
current_period_start=now,
current_period_end=now + timedelta(days=period_days),
created_at=now,
)
subscriptions_db[sub.id] = sub
return sub
def cancel(self, subscription_id: str) -> Subscription:
sub = subscriptions_db.get(subscription_id)
if not sub:
raise ValueError("Subscription not found")
sub.status = "cancelled"
return sub
def upgrade(
self, subscription_id: str, new_plan: SubscriptionPlan
) -> dict:
sub = subscriptions_db.get(subscription_id)
if not sub:
raise ValueError("Subscription not found")
days_remaining = (sub.current_period_end - datetime.utcnow()).days
proration = calculate_proration(
sub.plan, new_plan, days_remaining, sub.billing_cycle,
)
sub.plan = new_plan
return {
"subscription": sub,
"proration_charge": float(proration),
}
Calibración de subscription_service.py:
├── Tipo: Lógica de negocio → Confianza base: 30%
├── Ajustes:
│ ├── -10%: Depende de pricing_service (que tiene issues)
│ ├── -5%: Lógica de upgrade/cancel tiene implicaciones financieras
│ ├── -10%: No hay tests
│ └── +5%: Estructura clara y legible
├── Confianza final: 10%
├── Profundidad: Línea por línea (20+ min)
└── Qué verifico:
├── ⚠️ cancel() no hace refund ni calcula periodo restante
├── ⚠️ upgrade() cobra prorrateo pero no registra el cargo
├── ⚠️ No hay downgrade (solo upgrade)
├── ⚠️ No verifica que new_plan sea diferente de current plan
├── ⚠️ In-memory storage — necesita DB real
├── ⚠️ proration_charge se convierte a float (pierde precision)
└── → NEEDS SIGNIFICANT EDIT
Resumen de calibración del módulo:
Archivo | Confianza | Decisión
----------------------|-----------|------------------
models.py | 85% | Acepta
pricing_service.py | 5% | Editar significativamente
subscription_service.py| 10% | Editar significativamente
routes.py (no mostrado)| 45% | Editar después de fixes
La calibración te dice exactamente dónde invertir tu tiempo: casi nada en models.py, casi todo en pricing y subscription.
La Diferencia entre Calibración Correcta e Incorrecta
Caso 1: Over-calibration (confías de más)
Tarea: Generar función de validación de contraseña
Tu calibración: 70% ("es una función simple")
Lo que pasó:
- La función solo validaba longitud mínima
- No verificaba caracteres especiales
- No prevenía contraseñas comunes (password123)
- No tenía protección contra timing attacks
Calibración correcta: 20-30%
- Es una función de seguridad
- Tiene implicaciones de compliance
- Requiere conocimiento específico de best practices
Error: Confundiste "simple de leer" con "bajo riesgo"
Caso 2: Under-calibration (desconfías de más)
Tarea: Generar modelos Pydantic para un blog
Tu calibración: 25% ("no confío en AI")
Tiempo invertido: 30 minutos revisando 40 líneas de modelos
Lo que encontraste:
- Todo estaba correcto
- Campos razonables
- Tipos correctos
- Validaciones presentes
Calibración correcta: 75-85%
- Modelos de datos simples
- Patrón estándar
- Bajo riesgo
- 3 minutos de revisión habrían sido suficientes
Error: Gastaste 27 minutos extra sin encontrar nada
Caso 3: Calibración correcta
Tarea: Generar endpoint de webhook para procesar pagos de Stripe
Tu calibración: 15%
Tiempo invertido: 25 minutos
Lo que encontraste:
- No verificaba la firma del webhook (crítico)
- No manejaba eventos duplicados (idempotency)
- Hardcodeaba el webhook secret
- No tenía retry logic para procesamiento fallido
Resultado: Encontraste 4 issues críticos en 25 minutos.
Sin tu revisión exhaustiva, cualquiera de estos issues
podría haber causado un incidente en producción.
Calibración correcta: Sí. 15% para payment webhooks.
Conexión con Proyecto
Cómo usarás Trust Calibration en el Módulo 8
En el proyecto integrador recibirás un codebase con múltiples módulos. Tu tabla de calibración te guía:
- Antes de empezar: Clasifica cada archivo del codebase por tipo de tarea y asigna confianza base.
- Durante la revisión: Ajusta confianza por factores contextuales. ¿Hay tests? ¿Conoces el dominio?
- Priorización: Empieza por los archivos con calibración más baja (mayor riesgo). Si tienes 60 minutos para la revisión, gasta 40 en los archivos de 10-20% de confianza y 20 en los demás.
- Documentación: Para cada módulo revisado, documenta tu calibración, lo que encontraste, y si tu calibración fue correcta.
Troubleshooting
Problema 1: "Mi tabla no cubre todos mis casos"
Causa: La tabla de 15 tipos es un punto de partida, no exhaustiva. Solución: Agrega filas a tu tabla según tu contexto. Si trabajas con WebSockets frecuentemente, agrega "WebSocket handlers" con la confianza que consideres apropiada. Si trabajas con ML pipelines, agrega esa categoría. La tabla es tuya — personalízala.
Problema 2: "No sé si un factor sube o baja mi confianza"
Causa: Falta de experiencia evaluando factores. Solución: Regla simple: si el factor reduce tu capacidad de detectar errores (no conoces el dominio, no hay tests, el código es complejo) → baja confianza. Si el factor aumenta tu capacidad (conoces el dominio, hay tests, patrón estándar) → sube confianza.
Problema 3: "Mi calibración inicial siempre está equivocada"
Causa: Tu tabla base puede no reflejar tu experiencia con Claude Code específicamente. Solución: Empieza conservador (confianza baja) y sube gradualmente con experiencia. Es mejor invertir tiempo extra al principio que descubrir bugs después. Después de 20-30 experiences, tu tabla será precisa para tu contexto.
Problema 4: "Mi equipo tiene diferentes calibraciones"
Causa: Cada persona tiene diferente experiencia y contexto. Solución: Eso es normal y esperado. Lo importante es que cada persona tenga una calibración explícita, no que todos tengan la misma. En el código compartido (auth, pagos), el equipo debería acordar una calibración mínima: "código de seguridad siempre tiene confianza < 20%, independientemente de quién lo revise."
Problema 5: "No tengo tiempo para llevar un registro de calibración"
Causa: El registro se siente como trabajo extra. Solución: No necesitas un registro formal. Basta con actualizar mentalmente tu tabla: "la última vez que generé SQL con Claude Code, encontré N+1. Mi confianza en queries baja a 35%." Si quieres ser riguroso, un archivo de texto con 5 columnas es suficiente. Toma 30 segundos por entry.
Ejercicios
Ejercicio 1: Calibrar tareas cotidianas (Fácil)
Para cada tarea, asigna confianza base, aplica factores de ajuste, y define profundidad de revisión:
- Generar un archivo
docker-compose.ymlpara PostgreSQL + Redis + tu app - Crear una función que parsea fechas en 5 formatos diferentes
- Implementar un endpoint que borra la cuenta de un usuario y todos sus datos
- Generar type hints para 20 funciones existentes
Ver solución
1. docker-compose.yml
- Confianza base: 80% (Dockerfiles/CI config)
- Ajuste: +5% si conoces Docker bien, -5% si hay secrets (passwords de DB)
- Confianza final: ~80%
- Revisión: Rápida (2-3 min). Verificar: ports correctos, passwords no hardcoded (usar env vars), versiones de imágenes.
2. Parseo de fechas (5 formatos)
- Confianza base: 60% (función de utilidad)
- Ajuste: -10% por complejidad (múltiples formatos = edge cases), -5% por regex implícito
- Confianza final: ~45%
- Revisión: Detallada (10-15 min). Verificar: que cubra los 5 formatos, que maneje formatos inválidos, que maneje timezones si aplica, probar con inputs edge case.
3. Delete de cuenta y datos
- Confianza base: 25% (operación destructiva + compliance)
- Ajuste: -10% si hay regulaciones (GDPR), -10% sin tests, -5% por side effects (borrar en múltiples tablas)
- Confianza final: ~0-5%
- Revisión: Línea por línea (25-35 min). Verificar: que borre TODO (no deje datos huérfanos), que sea transaccional, que requiera confirmación, que tenga auth, que haga logging, GDPR compliance si aplica.
4. Type hints para funciones existentes
- Confianza base: 85% (documentación/boilerplate)
- Ajuste: +5% si las funciones son simples, -5% si las funciones tienen lógica compleja que Claude Code podría malinterpretar
- Confianza final: ~85%
- Revisión: Visual rápida (3-5 min). Verificar: que los tipos sean correctos (especialmente return types y Optional), que no introduzca errores de mypy.
Ejercicio 2: Encontrar calibración incorrecta (Medio)
Un developer tiene esta tabla de calibración. Encuentra los errores:
Mi tabla de calibración:
1. Endpoints REST → 80% (son siempre iguales)
2. SQL queries → 70% (SQL es simple)
3. Auth middleware → 60% (ya lo he hecho antes)
4. README.md → 30% (no confío en la info)
5. Regex validation → 75% (expresiones cortas)
6. Payment processing → 50% (es solo math)
Ver solución
Errores en la calibración:
-
Endpoints REST (80%): Demasiado alto como generalización. Un endpoint de CRUD puede ser 70%, pero un endpoint que maneja permisos o datos sensibles debería ser 30-40%. La justificación "son siempre iguales" ignora que los endpoints varían enormemente en riesgo.
-
SQL queries (70%): Peligrosamente alto. SQL tiene riesgo de injection, N+1, y lógica incorrecta. Debería ser 40-55%. La justificación "SQL es simple" es una trampa — SQL parece simple pero tiene trampas sutiles.
-
Auth middleware (60%): Muy alto para seguridad. Auth debería estar en 10-20% siempre. "Ya lo he hecho antes" sube tu familiaridad (+5-10%) pero no lo suficiente para compensar que es código de seguridad.
-
README.md (30%): Muy bajo. Documentación tiene riesgo bajo. 85-90% es apropiado. La preocupación de "info incorrecta" es válida pero se resuelve con una revisión de 2 minutos, no 15.
-
Regex validation (75%): Muy alto. Regex es una de las áreas donde AI es más impredecible. 15-25% es más apropiado. "Expresiones cortas" no reduce el riesgo — una regex de 10 caracteres puede tener catastrophic backtracking.
-
Payment processing (50%): Muy alto. Procesamiento financiero debería ser 10-20%. "Es solo math" ignora precision (float vs Decimal), compliance, edge cases de monedas, rounding, y el impacto de un error (pérdida financiera directa).
Patrón: Este developer calibra basándose en percepción de dificultad ("es simple", "son cortas") en vez de en impacto de error. Resultado: sobre-confía en código de alto riesgo y sub-confía en código de bajo riesgo.
Ejercicio 3: Calibrar un output real (Medio)
Claude Code generó esta función. Calibra: tipo de tarea, confianza base, factores de ajuste, confianza final, y profundidad de revisión. Después, revisa según tu calibración.
from datetime import datetime, timedelta
from typing import Optional
import jwt
import os
SECRET = os.getenv("JWT_SECRET")
ALGORITHM = "HS256"
def create_reset_token(user_email: str, expires_in: int = 3600) -> str:
payload = {
"sub": user_email,
"type": "password_reset",
"exp": datetime.utcnow() + timedelta(seconds=expires_in),
"iat": datetime.utcnow(),
}
return jwt.encode(payload, SECRET, algorithm=ALGORITHM)
def verify_reset_token(token: str) -> Optional[str]:
try:
payload = jwt.decode(token, SECRET, algorithms=[ALGORITHM])
if payload.get("type") != "password_reset":
return None
return payload.get("sub")
except jwt.ExpiredSignatureError:
return None
except jwt.InvalidTokenError:
return None
def reset_password(token: str, new_password: str) -> bool:
email = verify_reset_token(token)
if not email:
return False
# Update password in database
from database import get_user_by_email, update_user_password
user = get_user_by_email(email)
if not user:
return False
update_user_password(user.id, new_password)
return True
Ver solución
Calibración:
- Tipo de tarea: Auth/Security (password reset) → Confianza base: 15%
- Factores:
- -10%: Token-based auth con implicaciones de seguridad
- -5%: No hay tests
- +5%: Código relativamente corto y legible
- -5%: Import circular en reset_password (from database import...)
- Confianza final: 0% (mínimo práctico: tratar como desconfianza total)
- Profundidad: Línea por línea + verificar contra docs
Revisión línea por línea:
-
✅
SECRET = os.getenv("JWT_SECRET")— Sin fallback, bien. Pero si JWT_SECRET no está seteado, SECRET es None → jwt.encode fallará con error críptico. Debería validar que SECRET existe al startup. -
⚠️
expires_in: int = 3600— 1 hora para reset token. ¿Es apropiado? La mayoría de servicios usan 15-30 minutos. 1 hora es generoso para un atacante. -
⚠️
verify_reset_token— Retorna None para cualquier error. No distingue entre token expirado (le dices al usuario "tu link expiró, pide uno nuevo") y token inválido (posible ataque). El UX y la seguridad se beneficiarían de distinguir estos casos. -
⚠️
reset_password— No hasheanew_password. Llamaupdate_user_password(user.id, new_password)con la password en texto plano. Siupdate_user_passwordno hashea internamente, la password se guarda en texto plano en la base de datos. Issue CRÍTICO. -
⚠️
reset_password— No invalida el token después de usarlo. Un token de reset puede usarse múltiples veces hasta que expire. Esto permite a un atacante que intercepte el token cambiar la password múltiples veces. -
⚠️ Import circular —
from database import...dentro de la función. Funciona pero es un code smell que puede causar problemas. -
⚠️ No hay rate limiting — Un atacante puede intentar miles de tokens por fuerza bruta.
-
⚠️ No hay validación de complejidad de
new_password— La nueva contraseña puede ser "1".
Decisión: RECHAZAR Y REGENERAR. Los issues 4 (no hashea password) y 5 (no invalida token) son deal-breakers de seguridad. La función tiene la forma correcta pero falla en los detalles que importan.
Ejercicio 4: Construir tu tabla personalizada (Difícil)
Crea tu propia tabla de Trust Calibration con al menos 10 tipos de tarea relevantes para tu trabajo. Para cada una:
- Tipo de tarea
- Confianza base (%)
- Top 3 cosas que verificar
- Un factor que sube tu confianza
- Un factor que baja tu confianza
Ver solución
No hay respuesta única. Tu tabla debería cumplir estos criterios:
- ✅ Tiene al menos 3 niveles de confianza distintos (no todo en 50%)
- ✅ Código de seguridad está en 10-25%
- ✅ Boilerplate y docs están en 75-90%
- ✅ Lógica de negocio está en 25-40%
- ✅ Cada entrada tiene "qué verificar" específico (no solo "revisar")
- ✅ Los factores de ajuste son concretos, no vagos
Ejemplo para un backend developer en SaaS:
| Tipo de tarea | Confianza | Top 3 verificaciones | Sube si... | Baja si... |
|---|---|---|---|---|
| Modelos de datos | 80% | Campos, tipos, validaciones | Dominio familiar | Relaciones complejas |
| CRUD endpoints | 65% | Validaciones, auth, status codes | Tests existen | Datos sensibles |
| Auth/JWT | 15% | Cada línea, contra docs, tests | Librería madura | Custom implementation |
| SQL queries | 45% | Injection, N+1, lógica | ORM usado bien | Raw SQL |
| Background jobs | 40% | Retry logic, idempotency, errors | Patrón estándar | State complejo |
| WebSocket handlers | 35% | Connection management, auth, memory leaks | Dominio familiar | Concurrencia |
| Email templates | 80% | Contenido correcto, variables | Texto simple | HTML complejo |
| API integrations | 35% | Error handling, retry, API correcta | API bien documentada | API cambió reciente |
| Config files | 85% | Secrets no hardcoded, valores | Setup estándar | Multi-environment |
| Migrations | 30% | Reversibilidad, data loss, locks | Schema simple | Datos existentes |
Resumen
En esta cápsula aprendiste:
- Trust Calibration convierte "creo que está bien" en un proceso estructurado con confianza cuantificada por tipo de tarea
- La tabla de 15 tipos de tarea te da un punto de partida concreto para calibrar tu confianza
- Factores de ajuste suben o bajan tu confianza base: tests, familiaridad, complejidad, seguridad, track record
- Trust Debt se acumula cuando confías de más — los problemas no desaparecen, se acumulan silenciosamente
- Tu tabla de calibración se actualiza con experiencia — empieza conservador y ajusta con datos reales
- La calibración correcta invierte tiempo proporcional al riesgo: 30 minutos en auth, 2 minutos en modelos
- Over-calibration (confiar de más) y under-calibration (desconfiar de más) son ambos costosos
Próxima cápsula: Ejercicio integrador — aplicar los 3 mental models juntos a escenarios reales con código.
Recursos Adicionales
- Thinking in Bets — Annie Duke - Calibración de confianza y toma de decisiones bajo incertidumbre
- Superforecasting — Philip Tetlock - Cómo los mejores pronosticadores calibran su confianza
- Google — Code Review Developer Guide - Cómo Google prioriza por riesgo en code review
- OWASP — Risk Rating Methodology - Framework de evaluación de riesgo para seguridad
- Anthropic — Claude Code Documentation - Documentación oficial de Claude Code
- Risk-Based Testing — ISTQB - Principios de testing basado en riesgo aplicables a calibración de confianza
Debugging & Code Review with Claude Code — Módulo 2, Cápsula 04 Claude Code Agentic Development Path — Guía #6 de 11