El instinto ante features complejas es "déjame probar algo" — pero las decisiones arquitectónicas se esconden en el tercer modelo, el quinto edge case. El verdadero valor de plan mode es mover la conversación arquitectónica al texto antes del código. Caso real: el sistema de jurado comunitario de Pickful — 3.032 líneas, 119 specs en verde, un solo commit, cero retrabajo arquitectónico después.
Ante una feature compleja, el instinto de la mayoría es "déjame probar algo".
El problema: los sistemas complejos tienen una característica — las decisiones de arquitectura se esconden en el 3ᵉʳ modelo, el 5º edge case, la 8ª regla de puntos. Lanzarte al código y chocar con esas decisiones a medio camino, para volver atrás y cambiarlas, cuesta 10× más que haberlas hablado en texto desde el principio.
Usé el plan mode de Claude Code para construir TopicReview, el sistema de jurado comunitario de Pickful, y vi la versión extrema de esta desigualdad: un commit, 3.032 líneas, 119 specs en verde, entregado de una sola vez. Ninguno de los más de diez commits que siguieron fue un rehacer arquitectónico — todos son ajustes de parámetros, pulido de UI, parches de edge cases. El sistema lleva en pie desde entonces y hoy es central para cómo la comunidad se automodera.
Este artículo trata sobre por qué las features complejas necesitan plan mode primero, qué hace realmente la fase de plan, y cuándo la conversación está lo suficientemente madura para empezar a escribir código.
TopicReview es una votación comunitaria que decide si un post de baja calidad se elimina. Se resume en una frase — pero la especificación se despliega en capas:
La complejidad no está en ninguna regla individual — está en cómo interactúan las reglas entre sí. Cada regla nueva puede disparar un rollback en otra.
Cuando escribís de corrido, los problemas más difíciles no son los hechos visibles — son las preguntas que ni se te ocurrió hacer. Leyendo el código de TopicReview al revés, hay al menos cuatro muros con los que chocarías inevitablemente si te saltearas el plan:
Reglas de elegibilidad de jurados. Parece simplemente User.jurors_and_judges.sample(12). Pero las reglas reales son: excluir al autor del post, excluir a quien lo denunció, excluir a quien ya votó en la ronda inicial (para que no vuelva a votar en la apelación). Tres exclusiones apiladas. Si escribís el modelo de una tirada, te comés una o dos.
Pago diferido de puntos. Un veredicto remove normalmente dispara el pago a los jurados. Pero una apelación puede revocar un remove — y cuando lo hace, los jurados que votaron con el veredicto viejo quedan en el lado equivocado, así que hay que recalcular los pagos contra el nuevo veredicto. Por eso el veredicto remove debe esperar a que cierre la ventana de apelación de 24h antes de pagar a los jurados. Si no escribís esta regla, pagás primero y después terminás intentando recuperar puntos — diez veces más engorroso que pagar tarde.
Diseño de interfaz del job programado. CloseTopicReviewJob parece "cerrar una review". En la práctica maneja tres situaciones:
# Expiración de la ventana de votación inicial
CloseTopicReviewJob.set(wait_until: voting_ends_at).perform_later(review.id)
# Pago diferido a jurados tras un veredicto remove
CloseTopicReviewJob.set(wait: 24.hours).perform_later(review.id, award_juror_points: true)
# Expiración de la ventana de apelación
CloseTopicReviewJob.set(wait: 24.hours).perform_later(review.id, appeal_id: appeal.id)
Sin la planificación previa, escribís la primera firma y en el segundo caso te das cuenta de que la interfaz tiene que cambiar.
El muro más caro: ¿se puede apelar durante la remoción provisional? Cuando los votos remove cruzan el umbral, el post queda oculto (provisional), pero la review sigue en estado voting — no decided. ¿Puede el usuario apelar ya?
decided y appealedEsa sola decisión repercute hacia atrás y cambia los chequeos de parámetros de open_appeal! y la lógica de la máquina de estados. Decidirlo a mitad de camino = reescribir medio sistema.
El plan mode de Claude Code es un modo en el que está prohibido escribir código — Claude puede leer el repo, pensar en enfoques, discutir con vos, pero cualquier modificación de archivos queda bloqueada con hard-block hasta que apruebes un plan.
Esa restricción mecánica es el punto: fuerza a que la conversación a nivel arquitectónico ocurra en texto.
Algunas cosas que la fase de plan está haciendo en la práctica:
1. Dibujar la máquina de estados y los roles. 5 estados, 4 roles (jurado / juez / autor / denunciante), lo que cada rol puede y no puede hacer en cada estado — todo en unas líneas de markdown. Unas líneas vs. decenas de archivos. El costo de cambio son dos órdenes de magnitud distintos.
2. Recorrer el flujo de cada rol:
Donde sea que el recorrido se traba, sale una pregunta oculta: "¿los jurados ven los votos de otros jurados?", "¿qué puede hacer el autor durante la remoción provisional?"
3. Interrogar edge cases. La fase de plan no diseña el "camino normal" — hace a propósito las preguntas que normalmente no surgen:
finalize al mismo tiempo — ¿la carrera duplica pagos? (Añadir un campo juror_points_awarded para idempotencia.)El 95% de estas preguntas no aparece naturalmente mientras escribís código. La fase de plan te obliga a contestarlas una por una.
4. Libro mayor de puntos. El sistema de puntos es tan complejo que discutir no alcanza — hay que dibujar la tabla: cada flujo de puntos con su disparador, su monto y su camino de rollback. Una vez que el libro cuadra, todos los edge cases (reembolso provisional, reembolso de apelación, bonus) se reconcilian.
Un criterio duro:
closed (keep / remove / warn × con / sin apelación × provisional / no) — la podés contar de punta a puntaCuando llegás a ese punto, escribir código es traducir el plan a Ruby.
La primera entrega de este sistema:
d162f1e Add community moderation system with jury/judge review and appeals
63 files changed, 3032 insertions(+)
119 specs, 0 failures
63 archivos, 3.032 líneas, 119 specs en verde. Entregado de una sola vez.
Los más de diez commits que siguieron confirman que la arquitectura aguantó:
Apply legacy penalty (1pt) for posts created before 2026-03-26
Fix topic review appeal bugs: window mismatch and verdict not updated
Add topic_removed status for posts removed by community review
Default to keep verdict when review expires with zero votes
Reduce provisional removal penalty to 1pt during trial period
Allow topic creator to withdraw active reviews
Add handled tab to jury dashboard, fix tabs styling
Cada uno es ajuste / fix / pulido / pequeña feature. Ninguno es "volver a rediseñar la máquina de estados" o "hay que cambiar el modelo de puntos". El esqueleto estaba bien.
Ese es el verdadero beneficio del plan: la ejecución no se interrumpe. No hay "esperá, cómo va este camino" — el plan ya lo cubrió. No hay "no había pensado este edge case" — la fase de plan lo preguntó. No hay "esta interfaz hay que rediseñarla" — el plan ya la resolvió.
Horas escribiendo código, haciendo una sola cosa: traducir un diseño claro al teclado.
No toda tarea merece plan:
El beneficio del plan mode viene de bajar el costo de reescritura. Si la tarea no tiene riesgo de reescritura, plan es solo overhead.
"Pensar antes de actuar" suena a consejo de personalidad. Plan mode no es eso.
Plan mode es hacer que la conversación a nivel arquitectónico ocurra donde 10 palabras la cambian — no donde tienen que cambiar 30 archivos.
Bajo complejidad, hay que dar vuelta el dicho de la industria "words are cheap, code is expensive" — no significa "escribí código primero y vemos" (eso solo vale cuando la brecha de costo es chica), significa usar esa brecha: poner la conversación cara por delante, en el medio barato.
3.000 líneas en un solo commit se siente increíble. No porque escriba rápido — porque el plan convirtió "escribir" en un acto puramente mecánico.