Cualquier acción que no puede deshacerse pasa por dos fases. Hex no aprueba un cableado destructivo sin este patrón. Es la única defensa que aguanta contra un modelo inyectado, un modelo confundido, o un modelo simplemente apresurado.
Fase 1, dry-run. El modelo llama la tool con dry_run=true. La tool no ejecuta nada. Solo calcula y devuelve qué pasaría: qué se borra, qué se invalida, qué se notifica, qué retención queda. Esto es lo que el modelo (y vos, vía audit log) puede inspeccionar antes de comprometer.
Fase 2, confirmación. El modelo presenta el preview al humano, espera el OK explícito, y solo entonces llama otra vez con dry_run=false y un confirm_token que vino del preview. La tool valida el token y, si coincide, ejecuta.
Confirmación generada por el modelo. El modelo dice "voy a borrar X, ¿confirmás?" y luego llama la confirmación sin esperar. Eso no es dos fases. es una fase con teatro. La confirmación tiene que cruzar a un canal distinto (el humano, otra app, una sesión separada) y volver.
Token de confirmación inventado. Si el modelo puede generar el confirm_token, no hay validación. El token tiene que venir del runtime (de la fase 1) y la fase 2 tiene que rechazar tokens que no emitiste.
Dry-run que igual escribe. Algunos "dry-runs" reservan recursos, escriben logs de "intento", o disparan webhooks. Eso ya no es dry. Tu dry-run tiene que ser idéntico a no hacer nada desde afuera, excepto por la respuesta al modelo.
Cuando una acción es irreversible, la prudencia es estructural. Si tu cableado depende de que el modelo "elija bien", no tenés prudencia. tenés esperanza.
A la derecha hay siete pasos. ponelos en orden. Hay UN orden correcto. Cualquier otro deja un agujero.