IA · carrera · criterio-tecnico · code-review · manifiesto

Aprender el lenguaje dejó de ser el reto (y por eso este blog existe)

Alejandro Quiroz8 min de lectura

Diez años midiendo mi carrera en lenguajes aprendidos, justo para llegar a la época donde el lenguaje es lo primero que la IA regala. Esto es Jako's hub y esto es lo que sí vale.

Hoy puedes escribir código en un lenguaje que nunca has visto.

Le pides a una IA un formulario de registro en Go, y en veinte segundos tienes algo que compila y que además se ve bien. No sabes Go. No importa. La parte que a mí me tomó meses —pelearme con la sintaxis hasta que dejó de estorbarme— hoy te la resuelven mientras te preparas un café. Eso no es una amenaza ni una tragedia: es un hecho, y ya pasó.

La parte incómoda viene después. Esa era la parte fácil, y era exactamente la que todos usábamos para medir si alguien "sabía programar". Ahora que es gratis, quedó a la vista lo que siempre fue lo difícil: saber si eso que te entregaron está bien, por qué está mal, y qué va a pasar con ese código en tres meses cuando quinientas personas lo usen al mismo tiempo un viernes de descuentos.

Me llamo Alejandro Quiroz. Casi todo el mundo me dice Jako, y por eso este lugar se llama Jako's hub. Vivo en Medellín, llevo más de diez años escribiendo software y hoy soy Tech Lead Frontend en Endava para la cuenta de Lululemon Athletica: un equipo de seis personas, un e-commerce de alto tráfico, Next.js y Node todos los días. Este es el primer post de un blog que debí haber empezado hace ocho años.

El error: pasé una década midiendo la cosa equivocada

Mi carrera, contada como la cuenta un CV, es una lista de tecnologías: PHP vanilla y SQL crudo en 2013, Symfony después, luego React, luego React Native, hoy Next.js. Cada salto se sentía como subir un escalón. Cada línea nueva en la lista se sentía como "ya soy mejor desarrollador".

En 2013, mi primer trabajo de verdad fue un ERP inmobiliario: un proyecto legacy con años encima, clases llenas de consultas raw y condicionales apilados para decidir qué string de SQL se terminaba armando. El sistema funcionaba. Ese no era el punto. El punto era que no había prácticas serias de filtrado en esas consultas y que la forma de hablar con la base de datos no seguía ningún estándar de la época —y para entonces ya se hablaba en todas partes de lo inseguro que era armar queries raw a mano—. Nadie estaba pidiendo arreglarlo, y yo tenía dos restricciones al mismo tiempo. Mi jefe no quería meterle una librería externa más al proyecto. Y yo no podía llegar de nuevo a reescribir media aplicación por mi cuenta, porque eso no se le hace a un sistema que ya está en producción y que no es tuyo.

Así que hice lo único que me quedaba. En ratos libres y en las horas de almuerzo escribí un par de archivos: le hice ingeniería inversa a Active Record —ya sabía cómo funcionaba por Yii— y armé una versión mínima que resolviera nuestro caso. No la solté sobre todo el sistema. La implementé solo en el módulo que tenía a cargo, ese donde si se rompía me rompía a mí. Cuando ya estaba funcionando ahí, se la propuse a mi jefe en un pull request.

La amó. De ahí en adelante fuimos migrando consultas poco a poco, módulo por módulo, y esos dos archivos crecieron durante años hasta volverse la forma en que el equipo entero hablaba con la base de datos.

Es la primera vez que cuento esta historia en público. Trece años, y nunca la escribí en ningún lado. Fíjate en lo que ya sabía hacer en mi primer trabajo sin saber que tenía nombre: entender la restricción real en vez de pelearme con ella, probar la idea en el pedazo donde el riesgo era mío, y convencer con algo que ya funcionaba en lugar de con una opinión en una reunión. Eso —no el ORM— es lo que valía la pena contar, y me lo guardé.

Y aquí está el error del que quiero hablar: durante todos esos años, lo que más quise hacer fue enseñarle a otros lo que iba aprendiendo. Desde el principio. Le explicaba cosas a compañeros en el escritorio de al lado, después en revisiones de código, después mentoreando gente del equipo. Pero cada vez que pensé en escribirlo público, me dije lo mismo: "cuando sepa un poco más".

Ese "un poco más" no llega nunca. No existe el día en que te sientes suficientemente experto. Lo que existe es la lista de tecnologías creciendo, y con ella la ilusión de que el conocimiento que vale es el que estás acumulando, no el que ya podrías estar entregando. Esperé diez años un permiso que nadie iba a darme.

El quiebre: el cuello de botella dejó de ser escribir

El último año cambió cómo trabaja mi equipo. Copilot y agentes en el día a día, todos los días, en un producto con tráfico real. Y lo que pasó no fue lo que la gente asume.

No es que escribamos más rápido y ya. Es que el trabajo se movió de lugar. Antes, el cuello de botella era producir el código; revisar era relativamente barato porque el código llegaba a tu revisión con las cicatrices visibles: nombres raros, un TODO olvidado, una función de 200 líneas. Se veía de dónde venía y en qué estaba pensando la persona que lo escribió.

El código generado no tiene cicatrices. Llega limpio, con nombres razonables, con tests que pasan, formateado, comentado. Y puede estar profundamente mal por razones que no se ven en el diff: una consulta por ítem dentro de un map, un useEffect que refetchea en cada render en la página con más tráfico del sitio, una función duplicada que ya existía tres carpetas más arriba con otro nombre. GitClear analizó 211 millones de líneas y encontró que 2024 fue el primer año registrado en el que hubo más código copiado/pegado dentro de un commit que código movido (refactorizado). Eso no es una opinión sobre la IA: es el rastro que deja en los repositorios.

A mí me cayó la ficha con un merge request que aprobé de afán. Un compañero venía tocando un archivo que compartíamos, y entre sus cambios había uno que no tenía nada que ver con el ticket que le habían asignado: había eliminado el atributo que habilitaba la virtualización en una lista de productos. Yo revisé por encima, vi que el resto cuadraba con lo que él tenía que hacer, y aprobé. Se fue a producción. El impacto no fue grave, pero nos reportaron el error, y cuando encontramos la causa lo importante no fue que él se hubiera equivocado.

Todavía no sé si ese cambio salió de una sugerencia de la IA o simplemente de un descuido, y honestamente da igual: el punto es que un cambio que nadie pidió atravesó una revisión sin que nadie lo notara. Y va a seguir pasando, más seguido, porque hoy el diff que te llega a revisar es más grande y llega más limpio. Yo revisé si el código estaba bien. No revisé si el código era lo que se había pedido.

Ahí entendí qué es lo que realmente aporto después de diez años, y no es la sintaxis. Es saber dónde se cuelan los errores que nadie escribió a propósito. Eso es lo que nunca escribí en ningún lado.

Lo que sí funciona: no usar IA mejor, sino controlarla mejor

La conversación pública sobre programar con IA está atascada en el prompt: qué le digo, cómo se lo digo, qué modelo uso. Mi opinión, sin diplomacia: eso importa mucho menos de lo que crees. Lo que decide si el resultado sirve es el proceso de control alrededor.

Tres cosas que sí cambiaron mis resultados, y que van a ser buena parte de lo que escriba aquí:

1. Fases verificables antes de una sola línea. Nada de "hazme el carrito". El trabajo se parte en fases y cada fase se define por cómo se comprueba, no por lo que hace:

# Fase 3 — Carrito: persistencia entre sesiones

## Qué debe quedar funcionando
- [ ] El carrito sobrevive un refresh (anónimo y con sesión iniciada)
- [ ] Al iniciar sesión, el carrito anónimo se fusiona con el guardado

## Cómo lo verifico (definido ANTES de generar código)
- Test: fusionar dos carritos con el mismo SKU suma cantidades, no duplica líneas
- Manual: agrego producto en incógnito → inicio sesión → la línea sigue ahí

## Fuera de alcance en esta fase
- Cupones, impuestos, cálculo de envío

Con eso, la IA no decide el alcance. Tú decides el alcance y la IA llena el espacio que le dejaste. Y cuando entrega, ya tienes contra qué comparar: no revisas "si se ve bien", revisas si cumple una lista que escribiste con la cabeza fría.

2. La decisión se documenta aparte del código. Un ADR (Architecture Decision Record) es un archivo corto, feo y de enorme valor:

# ADR-004 — El estado del carrito vive en el servidor
Estado: aceptada · Fecha: 2026-05-14
Contexto: el carrito en localStorage se desincroniza entre pestañas y se pierde al cambiar de dispositivo.
Decisión: el servidor es la fuente de verdad; el cliente solo cachea.
Consecuencias: +1 llamada al montar; se necesita un endpoint de fusión al iniciar sesión.
Alternativas descartadas: solo localStorage (barato, pero rompe multi-dispositivo).

El punto no es la burocracia. El punto es que dentro de seis meses, cuando una IA proponga "simplificar" moviendo el carrito al cliente, exista un archivo que diga por qué eso ya se descartó y qué se rompe si lo haces. La memoria del equipo no puede vivir en la cabeza del que estaba ese día.

3. Un revisor que compara el diff contra el ticket, no contra el estilo. Después del incidente de la virtualización hicimos lo que más me gusta de esta época: usamos IA para tapar un hueco que la IA hace más grande. Montamos un agente revisor, pero deliberadamente no para revisar formato —para eso ya está el linter y no era ahí donde nos estábamos cayendo—. El agente recibe los criterios de aceptación y el alcance del ticket, lee el diff del pull request y responde una sola pregunta: ¿estos cambios corresponden a esos criterios, y a nada más?

Levanta bandera en los dos sentidos. Si aparece código que no tiene nada que ver con el objetivo del ticket, lo marca. Si falta un criterio de aceptación que quedó sin cumplir, también lo marca. Nada más. Ese alcance tan estrecho es justamente lo que lo hace útil.

Lo interesante es en qué terminó. Lo montamos para atrapar cambios no intencionados —el caso del atributo borrado— y hoy lo usamos sobre todo al revés: para verificar que lo que cada quien entregó sí cumple lo que el ticket pedía. Resultó que el problema nunca fue solo el código de más. Era que nadie estaba comparando sistemáticamente el resultado contra lo que se había acordado.

Eso es lo que quiero que sea este blog: no tutoriales de sintaxis —para eso ya tienes al modelo abierto en otra pestaña—, sino el criterio que hace que lo generado sirva. Post-mortems de cosas que salieron mal, anti-tutoriales sobre cuándo no usar la herramienta de moda, comparativas con opinión y no con "depende". Y si estás empezando y ni siquiera sabes cuál rama del desarrollo te puede emocionar, hay una página aparte para eso: Pregúntale a Jako. No enseña, orienta. Es distinto.

El gotcha: escribir esto no te transfiere el criterio

Aquí la parte honesta, que es la que me interesa que quede clara desde el primer post.

El criterio no se descarga leyendo. Yo puedo describirte por qué una consulta dentro de un map te va a explotar en producción, y vas a entenderlo intelectualmente, y aun así la primera vez que te pase no vas a verlo venir. Lo máximo que puede hacer un texto es que la segunda vez lo reconozcas en cinco minutos en lugar de en dos semanas. Ese es el negocio real de este blog y no voy a prometer más.

Hay dos formas de perder en esta época, no una. La obvia: delegarle todo a la IA y nunca construir el modelo mental para saber cuándo te está mintiendo. La menos obvia, y que veo en gente con experiencia: volverte el que desconfía de todo, escribe cada línea a mano para "no perder el toque", y termina siendo el más lento del equipo mientras discute con el que ya entregó. Las dos son la misma falla vista desde lados opuestos: no haber definido dónde va tu juicio y dónde va la máquina.

Y algo más: varias de las opiniones que escriba aquí van a envejecer mal. Las herramientas cambian cada tres meses. Cuando algo que publiqué deje de ser cierto, voy a escribir el post que lo contradice en vez de borrarlo calladito.

La regla

Si no puedes explicar por qué ese código está bien, no importa quién lo escribió: todavía no es tuyo.


Si esto te sirvió, quédate. Voy a publicar aquí lo que llevo diez años diciéndole a la gente en revisiones de código y en conversaciones de pasillo, que resulta que era el trabajo real todo el tiempo.

GitHub: alejandro-devop · LinkedIn: alejandro-quiroz-serna

Fuente citada: GitClear — AI Copilot Code Quality 2025 Research


Lo que hubiera querido saber antes: que la parte que yo estaba practicando —escribir el código— era la que se iba a volver gratis, y la que daba por hecha —saber por qué está mal— era la única que iba a valer.