Cómo un runner promedio carga sus entrenamientos
Ver la imagen, cambiar de pantalla, acordarme del ritmo, repetir. Lo cambié por un agente, una skill y una conexión a Garmin.
Me sigue importando el cómo. Así armé un equipo de agentes que sigue mis reglas.
Un día dejé corriendo un script que le pasaba tareas a un equipo de agentes, una tras otra, y me fui a estudiar. Dos horas después había 4 commits, todos con los chequeos en verde, y 67 decisiones escritas esperando mi revisión. No tuve que revertir ninguna.
Pero esto no empezó con los agentes. Empezó con algo que me importa desde antes: entender cómo está hecho lo que construyo.
En la comunidad siempre se valoró cómo se escribía el código. Bien ordenado, era escalable. Tanto, que diseñábamos para escalar hasta el to-do list personal que iban a usar exactamente una persona y su mamá. Y sobre todo, le hacía la vida más fácil al resto del equipo, al que llegara después o a uno mismo en seis meses, a la hora de revisar, mantener o depurar.
Con el boom de los agentes, eso parece importar cada vez menos. A comienzos de 2025, Andrej Karpathy bautizó el vibe coding: programar entregándose a la IA y olvidándose de que el código existe. Desde entonces hay devs que lo abrazaron por completo, y otros que lo viven casi como un duelo. Simon Højberg lo describe como una crisis de identidad del programador: la pregunta ya no es si la IA escribe bien, sino qué queda de nosotros si el código ya no lo escribimos nosotros. Del otro lado, los que más delegan lo cuentan como una reinvención del oficio, no como una pérdida.
Yo estoy en algún punto intermedio. Delego cada vez más, pero hay una parte del sistema que sé que se puede romper, y esa quiero tenerla a la vista. Lo de la crisis de identidad da para otro post. Por ahora, este es mi intento de no elegir entre velocidad y control.
Antes del boom de los agentes, entre 2023 y parte de 2025, cuando todavía no daban tan buenos resultados desarrollando software, en mi trabajo teníamos una forma clara de ordenar los proyectos: requerimientos, módulos, servicios, arquitectura y convenciones de código limpio. Funcionaba. Cualquiera del equipo sabía dónde estaba la pieza de código a tocar, y si algo fallaba, podíamos intuir rápido en qué parte del proyecto estaba el error.
Con la llegada de los agentes, y de la orquestación de varios a la vez, mantener el código como uno quería, con los patrones que sigue un equipo, se volvió difícil. Claro, podíamos darle la instrucción general en un prompt: qué archivos tocar, qué rutas revisar, qué patrón seguir. Recuerdo que mi primera forma de trabajar con agentes en proyectos grandes, sin que se perdieran, era escribirles tres párrafos: dónde encontrar lo que debían cambiar, la “inspiración de código” a seguir y el objetivo final.
Luego llegaron las skills, que permitieron definir todos esos patrones que se siguen una y otra vez, y dejar de explicarle al agente cómo hacer las cosas en cada prompt. Porque una cosa es lo que queríamos, pero para algunas personas sigue importando el cómo.
Y esto último es algo que hasta hoy me cuesta un poco asumir. Siempre me ha importado cómo está construido algo: entender por qué una feature o una pieza se hizo de tal forma, o por qué se tomó tal decisión. Con agentes cada vez más potentes, seguirle el rastro a las decisiones de la IA a un nivel tan específico se hace cada vez más difícil.
El debate sobre si hay que revisar el código o no sigue abierto. Yo creo que hay que encontrar un balance, por lo menos por ahora: no revisarlo todo, pero tampoco nada. Tener un flujo que me permita saber qué se hizo, entender cómo se hizo a nivel general y, si quiero bajar al detalle de algo específico, tener un registro donde buscarlo. Ya saben, el famoso cuello de botella actual: human in the loop, que le quita algo de la velocidad desorbitante con la que hoy se puede desarrollar. Por eso lo pongo solo en los puntos que importan.
Así que lo escribí. Y como lo que no está escrito no existe, ni para mí ni para el agente, lo escribí como código.
Lo que escribí se llama bluedot, y es un plugin de Claude Code. Para quien no lo usa, tres ideas:
/algo) y hooks (scripts que corren en momentos
fijos, como al terminar un turno). La documentación
oficial lo explica completo.Así se declara un subagente: un archivo Markdown con su rol, sus herramientas y su modelo.
---
name: planner
description: Turns a development task into a plan with
steps per piece, required tests, acceptance criteria
and "ask before" items. It never writes code.
tools: Read, Grep, Glob, Write, Skill
model: opus
skills:
- bluedot:conventions
---
Estos principios los fui extrayendo e iterando en varios proyectos freelance, de trabajo y personales. Tampoco quise abarcar todos los stacks posibles: por ahora cubren aquel con el que desarrollo los proyectos más grandes y que tengo más probado. Si mañana hay que hacer algo en, por ejemplo, Rust, esa forma de hacer las cosas no entra por un proyecto puntual. Tiene que repetirse en varios proyectos para convertirse en regla, y desde ahí se itera. Es el principio 2 aplicado a las propias convenciones.
core tiene las reglas de negocio; la
web, la API o un agente de IA son entradas que la usan, nunca la reimplementan. Cuando algo
falla, sé dónde buscar.core → base de datos. Los límites
los vigila el lint, no la memoria. Ni la mía ni la del agente.Así se ve un caso de uso en core: una función que recibe sus dependencias (las inyecta Awilix)
y no sabe quién la llama.
export const updateMyProfileUseCase =
({ actor, clock, auditLog, accounts }: Deps) =>
async (command: UpdateMyProfileCommand) => {
const user = requireAuthenticatedUser(actor);
const account = await accounts.findById(user, user.id);
if (!account) throw new UserNotFoundError();
ensureExpectedVersion(account, command.expectedVersion);
account.updateProfile(command, clock.now());
auditLog.stage({ action: 'update', entityId: account.id });
await accounts.save(user, account);
return account;
};
Y esta es la regla que impide que core importe el framework web. Si alguien lo intenta, persona
o agente, el lint falla:
// eslint.config.mjs (simplificado)
{
files: ['packages/core/**'],
rules: {
'no-restricted-imports': ['error', {
patterns: [
{ group: ['hono', 'react', 'next'],
message: 'core no conoce el framework' },
{ group: ['@app/api', '@app/web'],
message: 'entradas → core, nunca al revés' },
],
}],
},
}
Qué es exactamente core, cómo armo la inyección de dependencias y por qué: eso da para otro post.
Cada vez delego más, pero me sigue interesando el cómo de las cosas. Por eso, para delegar más y a la vez estar más seguro de que el trabajo del agente está correcto, o como “yo quiero”, armé uno de los flujos típicos que se ven hoy: un equipo de agentes de desarrollo. Cada uno con su tarea, sus responsabilidades y el modelo que le corresponde según cuánto criterio necesita.
| Rol | Modelo | Por qué |
|---|---|---|
| Planificador | Opus | Decide piezas, skills y qué preguntar |
| Ejecutor | Sonnet | Sigue un plan claro; corre en paralelo |
| Revisor de convenciones | Sonnet | Compara contra un checklist |
| Auditor de seguridad | Opus | Busca lo que no está en el checklist |
| Tester E2E | Sonnet | Recorre la pantalla con un navegador |
Los coordina un orquestador: el comando /bluedot:task <lo que quiero>.
Plan
planner · opus
Piezas afectadas, skills a cargar y preguntas «ask before».
decido yo
Apruebo el plan y respondo cada «ask before».
Implementación
executor · sonnet · en paralelo
Un ejecutor por paso del plan.
Gates
hook
Lint, type-check y tests después de cada paso.
si falla o no corrió → vuelve al ejecutor
Revisión de convenciones
convention-reviewer · sonnet
Contra el checklist de cada pieza.
máx. 2 rondas por hallazgo
Seguridadsi aplica
security-auditor · opus
Si toca autenticación, permisos, rutas, configuración o dependencias.
E2Esi aplica
e2e-tester · sonnet
Si cambió una pantalla o un flujo.
Resumen de cierre
orquestador
Necesito que decidas / Riesgos / Verificado automáticamente.
decido yo
Leo el resumen y decido lo pendiente.
Después de cada paso, y al terminar cada turno, corre un hook con los gates: lint, type-check y tests. La regla más importante salió de QOne: un turno que solo tocó la configuración del repo terminó sin gates y sin avisar. Un gate puede “pasar” sin haber revisado nada, y por eso un gate que no corrió no es un gate verde. Así queda en el hook:
# 0 tareas en un proyecto con piezas: "no corrió", nunca verde.
count_turbo_tasks "${tasks[@]}"
if [ "$task_count" -eq 0 ] && [ "$have_pieces" = "1" ]; then
report+="${label}: NOT RUN (0 tasks, project has pieces)\n"
not_run=1
return
fi
Esta es la parte que responde a mi “me importa el cómo”. Son tres mecanismos.
Preguntas “ask before”. El plan se detiene antes de una dependencia nueva, un cambio de esquema o cualquier cosa irreversible. Nada de eso avanza sin que yo responda.
ADRs. Cada decisión que requiere criterio queda escrita: qué se decidió, por qué y qué otras opciones había. Si en tres meses quiero saber por qué algo se hizo así, está ahí. Vale también para las reglas: cualquiera, humano o agente, puede proponer un cambio a las convenciones, pero solo yo lo apruebo. Los agentes nunca cambian las reglas.
y el próximo proyecto ya parte con la regla
El resumen de cierre. Cada tarea termina igual: en español, con tres secciones y sin listar archivo por archivo. Es lo primero que leo. Uno de ejemplo, adaptado de una tarea real:
**Necesito que decidas**
- La tarea agrega dos variables de entorno. Dales valor en tu
`.env` local antes de levantar el proyecto: ningún agente
toca ese archivo.
- Hay un ADR propuesto que se aparta de lo que pedía la tarea.
Recomiendo aceptarlo.
**Riesgos**
- Una parte solo se probó con la base de datos de tests.
- Falta definir quién custodia el respaldo que propone el ADR.
**Verificado automáticamente**
lint, test:tooling, check-types y test en verde; ningún gate
"no corrió". Convenciones y seguridad: 2 rondas cada una, sin
hallazgos abiertos. E2E: no aplica.
Y el versionado: cada proyecto fija una versión exacta del plugin. Nunca se actualiza solo; subir de versión es una tarea planificada, guiada por el CHANGELOG. Si un proyecto necesita desviarse de una regla, lo deja registrado como excepción en un ADR.
QOne es mi plataforma para coordinar pabellones quirúrgicos, y la estoy migrando a un monorepo nuevo con bluedot. Es la prueba más dura que le he puesto.
Partí por extraer lo que el código antiguo hacía. El comando /bluedot:extract-requirements leyó
el módulo de identidad y produjo 31 reglas de negocio, cada una con su archivo y línea de
origen; 24 discrepancias entre el código y la documentación, incluidos bugs reales; y 14
tareas listas para ejecutar. Cómo migrar un repo antiguo con agentes merece su propio post.
Después vino la base del sistema: configuración, logs, multi-tenancy, auditoría, cifrado de datos
personales. Las últimas cuatro tareas las dejé corriendo solas, con un script que lanzaba
/bluedot:task una tras otra. Es el script del principio. En unas dos horas: 4 commits, cada
uno con los gates en verde, dos rondas de revisión de convenciones y dos de seguridad. El agente
tomó 67 decisiones y las dejó escritas para mi revisión. No tuve que revertir ninguna.
Lo más valioso fue lo que encontraron los agentes. Tres ejemplos, todos corregidos en la misma tarea y cada uno con su test:
Y eso no se quedó en QOne. Lo que falló volvió a bluedot como ADR y como regla nueva. Por ejemplo, el aislamiento de datos entre clientes ahora es obligatorio y se prueba con el mismo rol que usa la app. Todo proyecto nuevo parte con eso resuelto: es el ciclo de la figura 3, funcionando.
Esto me ha permitido mantener desarrollos en paralelo sin perder el control sobre los proyectos: sé qué se hizo, por qué, y dónde mirar si quiero bajar al detalle. Y me dejó tiempo para otras cosas: estudiar, concentrarme en proyectos de robótica e inteligencia artificial, como clasificar galaxias, y en las tareas de negocio e investigación que requieren pensamiento crítico y creatividad.
No está terminado. Sigo aprendiendo sobre desarrollo con agentes, a optimizar el consumo de tokens y a probar otras herramientas de desarrollo con IA. bluedot pasó de mis notas de Obsidian a un plugin versionado en cinco días, y va en la 0.10, no en la 1.0. Cada proyecto nuevo le sigue enseñando algo.
Cada vez delego más. Pero me sigue importando el cómo, y ahora queda escrito.
Si quieres ordenar el desarrollo de tu equipo con agentes, conversemos.
Siguiente registro: cómo migré un repo antiguo con agentes.