Cada vez que enseño PaellaDoc alguien me suelta la misma: “esto Codex te lo hace en diez minutos”.
Vale. Se lo he pedido a la Codex app (la de escritorio, no el CLI). Dos veces: la segunda, pidiéndole además que lo comprobara todo antes de entregar. Y he subido los tres repos a GitHub — el primer intento, el segundo y el de PaellaDoc — para que no tengas que fiarte de mí.
El primer prompt
Esto le he escrito a la Codex app un sábado por la tarde, iba con prisa:
/goal hazme una app de gestión familiar con svelte y fastapi
y sqlite que sea SOTA no me preguntes nada
Modelo gpt-5.6-sol. Después, dos mensajes más: “como la abro?” y “hazlo tu”. Diez minutos en total.
A PaellaDoc le he dado todavía menos:
Gestor familiar
Sin spec en ningún caso. La gente pide las apps así.
Diez minutos después
La Codex app ha entregado “Nido”. La portada es mejor que la de PaellaDoc, se lo concedo sin pelearme: paleta cálida, tipografía cuidada, saludo con tu nombre. En un vídeo de demo gana ella.
La portada de Nido tal cual la ha entregado la Codex app. Captura de mi sesión del 11 de julio.
Luego he hecho clic.
Clic en “Añadir tarea”, el botón principal de la app. No pasa nada. El modal no se abre.
Clic en “Tareas”. El menú la marca activa y el contenido se queda clavado en la portada.
Marco una tarea como hecha. El dato llega a la base de datos, el contador baja… y la pantalla se muere en esqueletos de carga.
Vuelvo a “Inicio”. Nada. La app entera está muerta hasta que le das a F5. Recargo y pruebo Calendario: mismo crash.
El menú dice Calendario. La miga de pan y el contenido, Inicio. La vista ha crasheado antes de pintarse.
La consola repite lo mismo todo el rato:
Uncaught Svelte error: invalid_snippet_arguments
A snippet function was passed invalid arguments.
Snippets should only be instantiated via `{@render ...}`
in Modal.svelte / in App.svelte
Y así se queda. Solo revive con F5.
Cuatro de las cinco secciones. Ningún formulario de alta. El bug es lo de menos: el proyecto traía un chequeo, svelte-check, y pasa con 0 errores sobre esta app. Puedes tener el build en verde y una app que nadie ha visto arrancar.
Lo que ha salido del otro lado
PaellaDoc ha tardado tres días y medio con la misma petición. Más feo, sí. Pero los 59 casos e2e que deja en el repo recorren la app en un navegador real: familia desde cero, adultos y niños con roles, presupuesto mensual por categoría, gastos con pagador y responsable que pasan de pendiente a pagado, el niño marca su tarea y el adulto la revisa. Hay un test cuyo único trabajo es comprobar que el niño no puede tocar tareas de otros.
El primer arranque: vacío, listo para tu familia. Sin datos ficticios sembrados. Esta captura la ha dejado el gate al validar el criterio “panel inicial vacío”; no la he hecho yo.
Cada criterio de aceptación deja su evidencia en el repo: captura más un JSON con lo comprobado. Este es de hoy:
{
"acceptance_criteria": "AC-US-01-4-3-02",
"verified": {
"finance": { "budget": "1000.00", "spent": "200.00",
"pending": "125.40", "paid": "74.60" },
"tasks_after_review": { "pending_adult_review": 0 },
"persisted_after_reload": true
}
}
1.000 menos 200, 800. 125,40 más 74,60, 200. Al céntimo. Y la captura que va al lado:
Página completa, dejada por el gate al validar AC-US-01-4-3-02. Los números coinciden con el JSON.
“¿Y si le pides que lo verifique?” Lo he hecho.
Es la objeción que me iba a poner todo el mundo, así que la he probado antes de escribir esto. Segunda sesión, mismo sábado, prompt ampliado:
/goal hazme una app de gestión familiar con svelte y fastapi
y sqlite que sea SOTA no me preguntes nada y comprueba que
todo va perfecto antes de entregármelo
Y esta vez la Codex app verificó de verdad. Su log de sesión lo cuenta: arrancó los servidores, vio el puerto 8000 ocupado y movió la API al 8010, recorrió la página con Playwright, sacó capturas, comprobó botones, probó la vista móvil y arregló un bug de calendario que encontró por el camino. Quince minutos. Cerró con “implementación y verificación completadas sin errores ni avisos”.
Se nota muchísimo. Esta vez los clics funcionan: he creado una tarea, la he completado, la he borrado; los formularios validan; hay estados de carga, de error y de vacío. Hasta trae 3 tests de backend, en verde.
Y aun así, mira la captura con calma:
Captura de las 18:45 de la tarde: el saludo dice “Buenos días”. La cabecera dice sábado; la tira de días pone el 11 en viernes. El mini-calendario de abajo, que sí acierta, contradice a los dos.
La app está congelada en el día en que se generó:
- “Sábado, 11 de julio” y “Buenos días, familia.” están escritos a fuego en la plantilla.
- El panel de “hoy” filtra los eventos con un
startsWith('2026-07-11')literal. Desde el día 12, vacío para siempre. - El formulario de gasto no tiene campo de fecha: el código manda
spent_on: '2026-07-11'fijo. Cada gasto que registres después del 11 de julio queda contabilizado el 11 de julio. Nadie lo notará hasta que el total del mes no cuadre. - La tira semanal es un
[7..13]clavado que además pone el día 11 bajo el viernes, siendo sábado. Dos widgets de la misma pantalla se contradicen, y la verificación visual que miró esa pantalla no lo vio.
La verificación pasó porque se hizo el mismo día que la app. Compró “funciona hoy”, en sentido literal. Y fue una pasada manual: no dejó ni un script para repetirla.
| Codex app, intento 1 | Codex app, intento 2 | PaellaDoc | |
|---|---|---|---|
| Tiempo | ~10 min | ~15 min | 3,5 días |
| Tokens procesados | 1.896.844 | 2.582.741 | 582.670.973 |
| Tokens escritos | 17.959 | 22.893 | 2.394.349 |
| Tests que quedan en el repo | 0 | 3 | 59 + 59 e2e |
| Verificación repetible | no | no | sí, con evidencia |
| Commits | 0 | 0 | 218 |
| Sobrevive al primer clic | no | sí | sí |
| Funciona al día siguiente | no | no | sí |
Las cosas extra que nadie ha pedido
Hay un gradiente claro: cuanto más dialogas con la Codex app, mejor sale. Sin verificación, la app murió al primer clic; con una frase más, sobrevive a los clics. Con más conversación, iría a más.
Pero hay un techo, y no es de esfuerzo: es que la generación no es determinista. Cada pasada añade superficie que nadie ha pedido, y esa superficie parece funcional sin estarlo. En estos dos intentos, verificados uno a uno:
- Flechas de “mes anterior / siguiente” que no hacen nada.
- Un enlace “Ver agenda completa →” que abre el formulario de crear plan, porque no existe ninguna agenda.
- Un evento decorativo, “Noche tranquila en casa · 20:30”, pintado todos los días entre los eventos reales.
- Una nota lateral fija, “Todo en calma. La semana está bien repartida.”, diga lo que diga la semana.
- Un presupuesto de “1.800 € previstos” (1.200 € en el primer intento) que nadie ha pedido y no se puede configurar.
- Una campana de notificaciones con su puntito rojo, sin notificaciones detrás.
En el gestor de PaellaDoc pasa lo contrario, y es la diferencia de fondo: las features son las que se han decidido, cada una lleva su criterio de aceptación validado, y no hay nada más. Ni un botón sin cablear. Hasta el estado vacío del primer arranque es una feature declarada, con su criterio y su captura de evidencia.
Qué compran los tokens
Yo sabía pedir verificación, y no ha bastado. La gente que escribe “hazme una app de gestión familiar” ni siquiera sabe que hay que pedirla. Si la verificación depende de que el usuario sepa pedirla, y de que una pasada de quince minutos vea todo lo que puede fallar mañana, no hay verificación.
Ahí se van los 582 millones de tokens de PaellaDoc. De escribir código, solo 2,39 millones; el resto es el loop ejecutando la app, mirándola y repitiendo, 541 veces. En el historial hay commits que se llaman literalmente “Reparar validación e2e: el resumen adulto refleja el estado final del flujo completo”. Ese commit existe porque algo no funcionaba y el gate no lo ha dejado pasar. Y los gates se quedan en el repo: el próximo cambio pasa por el mismo examen. Ese es todo el sentido de ejecutar un agente dentro de un gate en vez de fiarte de su propio visto bueno, que es la comparación que desarrollo en PaellaDoc vs Codex.
En justicia
Contra la Codex app no tengo nada. La velocidad es real, el gusto visual también, y el salto del intento 1 al intento 2 demuestra que escucha lo que le pides: verificó, esquivó un puerto ocupado, arregló un bug que encontró. Con alguien delante iterando, saldría.
Y el experimento es el que es: una app, dos prompts, un intento cada uno, el mismo sábado. Lo que he medido es la distancia entre “me lo ha comprobado” y un sistema donde comprobar no es opcional ni caduca.
Compruébalo
Los tres repos, publicados tal cual han salido, con el código sin tocar (el único añadido posterior es el README de cada uno):
- gestor-familiar-codex — arranca backend y frontend y haz un clic. El que sea.
- gestor-familiar-codex-verificado — ábrela cualquier día que no sea el 11 de julio de 2026. Mira el saludo, mira la tira semanal, añade un gasto y consulta con qué fecha se ha guardado.
- gestor-familiar-paelladoc — dentro van los 59 tests de backend, los 59 casos e2e, los 218 commits y la evidencia por criterio.
Si no lo has visto funcionar, no está hecho. Y haberlo visto funcionar ayer no cuenta.