Estoy commiteando especificaciones en coreano en vez de código — una app PWA + servidor con 3 páginas de especificación
(github.com/SoliEstre)Había algo que me molestaba continuamente al pedirle a la IA que programara. Queda el código resultante, pero se pierden la conversación y la intención que lo produjeron. Tres meses después, no hay a quién preguntarle: “¿por qué este código está así?”.
Así que probé invertir el enfoque. Commitear en git una especificación que contenga la intención, y tratar el código como un artefacto de build. Como prueba, construí y publiqué una pequeña app de principio a fin.
Es una PWA llamada Rimlog en la que la IA conecta notas anteriores con registros de lectura y aprendizaje. Sin servidor, sin registro, y los datos solo están en el navegador.
La app es bastante normal. Lo que quiero compartir es la forma en que la hice.
Enfoque
En la carpeta eux/ del repo hay 3 páginas de especificación en coreano. Toda la estructura de la app son 40 líneas, el widget de tarjetas de IA son 25 líneas, y el servidor de insights es una página. Están escritas con frases como estas.
saveCapture: guardar formulario de captura (nombre de la fuente, cita, mis pensamientos, etiquetas) — insertar al inicio de captures + reflejar en local storage + toast de “Guardado” + cambiar a la pestaña de historial.
Si pasas este archivo por una herramienta llamada EstreUX, sale código (lo llamo brew). El código generado lleva incrustado el hash de la especificación, y si modificas solo la especificación o solo el código, el pre-commit bloquea el commit. La idea es impedir con un gate el problema de que la especificación se vuelva mentira en el momento en que queda desactualizada.
También medí algunos números. Hice mediciones reales, por ejemplo revirtiendo un keypad numérico de 152 líneas que venía originalmente en el framework a una especificación de 28 líneas, y la cantidad de líneas que mantiene una persona se redujo entre 60% y 82%. El código generado en sí a veces termina siendo más largo que el original. Lo que se reduce es la parte que una persona lee y modifica. El registro de mediciones está en el repo.
El servidor también es una sola página de especificación
La demo en Pages es serverless, así que la IA funciona solo con un fallback por coincidencia de etiquetas. Para que funcionara bien agregué un servidor self-hosted, y esto también es un único archivo de Node sin dependencias, breweado desde una sola página de especificación. Se puede elegir el backend.
nvidia(por defecto): es la API gratuita de build.nvidia.com. Entrega una key sin registrar tarjeta, es compatible con OpenAI y ronda las 40 solicitudes por minuto, así que alcanza de sobra para un diario personalclaude-cli/codex-cli: en cada request llama aclaude -p/codex execcomo proceso hijo. Es una vía para reutilizar, sin API key, la suscripción de Claude/ChatGPT que ya estás pagandoopenai/google: simplemente proxy de key
Las keys y la autenticación solo están en el servidor y no salen al navegador.
Cosas de las que todavía no estoy seguro
Estoy ampliando la validación de consistencia especificación↔código, además del diff estático, con pruebas dinámicas basadas en propiedades, pero todavía falta calibrar los pesos. También encontré una clase de falsos positivos en la que el render del framework en un entorno DOM headless se comporta distinto al de un navegador real, así que otra tarea pendiente es elevar el entorno de validación a un navegador real. Si miran el historial de commits desde el inicio, quedó registrado en orden el proceso de scaffold → especificación → generación → pulido.
- Live: https://soliestre.github.io/Rimlog/
- Repo: https://github.com/SoliEstre/Rimlog
- Registro de build (detallado): https://estreui.tistory.com/5
Me dan curiosidad dos cosas. ¿Qué trampas le ven al enfoque de poner la especificación como SSoT? En particular, me interesa saber en qué puntos se encontraron con que la expresividad de la especificación no alcanza a seguirle el ritmo al código. Y respecto de reutilizar una suscripción usando claude -p como backend de una app, ¿qué problemas podrían aparecer en uso real (desde el punto de vista de rate limits, términos de uso y latencia)?
Aún no hay comentarios.