Había un ADR. Estaba escrito, versionado, asentado como decisión vigente: el ORM del proyecto era SQLAlchemy. La decisión tenía contexto, alternativas evaluadas, consecuencias asumidas. Era memoria viva del proyecto, exactamente lo que suponemos que deben ser estos artefactos.
Hasta que apareció una tarea de ingesta masiva. El copiloto, Claude Code con el modelo Opus 4.6, escribió la solución usando asyncpg COPY para ganar performance. Era una elección técnicamente razonable. Probablemente, en aislamiento, era la mejor opción. Pero no respetaba la decisión vigente, no la nombraba, no preguntaba si valía la pena revisarla, no sugería un ADR nuevo que la reemplazara. Simplemente lo implementó. Y lo implementó bien.
Esa última parte es la que más incomoda. Si hubiera implementado algo claramente malo, una revisión posterior lo hubiera atrapado más fácilmente. Pero como implementó algo plausible, el riesgo era mucho mayor: que entrara al sistema en silencio, dejara una excepción no declarada a una decisión arquitectónica vigente, y abriera la puerta a una fragmentación que solo se notaría meses después.
El ADR existía. Era recuperable. El copiloto lo había leído: la instrucción explícita era cargar adr.md en contexto antes de cualquier acción. Y aun así no apareció a tiempo para detener un cambio que lo contradecía.
El problema, mirado de cerca, no era la elección técnica. Tal vez asyncpg COPY era efectivamente la mejor opción para una ingesta masiva. El problema era otro: la decisión arquitectónica vigente no apareció como interlocutora. No fue obedecida, ni discutida, ni declarada como excepción, ni reemplazada por una decisión nueva. Quedó simplemente fuera del acto de decidir. Una arquitectura sana no prohíbe excepciones; prohíbe excepciones invisibles.
La respuesta correcta del copiloto no tenía que ser “usar SQLAlchemy”. Podía ser algo como: “Para esta ingesta masiva conviene considerar asyncpg COPY, pero eso contradice el ADR vigente sobre SQLAlchemy. Propongo tratarlo como excepción explícita o abrir un ADR nuevo que reemplace al anterior”. Una respuesta así no garantiza la mejor decisión técnica, pero sí garantiza que la decisión vigente participa del acto de decidir. Eso es uptake.
Sería cómodo llamarlo un fallo del modelo. Y en un sentido lo fue: el contexto estaba ahí, pero no entró en la decisión. Aun así, detenerse ahí sería perder el punto. El fallo más importante fue del sistema sociotécnico que asumió que cargar el documento equivalía a incorporarlo en la decisión.
En este caso particular, el problema se atrapó: salió a la luz al revisar el código antes de aceptarlo. Pero esa revisión no tenía separación estructural: la hizo la misma persona que había conducido la sesión con el copiloto, sobre un proyecto chico que se podía leer línea por línea. Funcionó por circunstancia, no por diseño. La pregunta no es si los fallos de uptake se pueden atrapar. Es cómo se atrapan cuando el copiloto produce más rápido de lo que un humano puede revisar.
El cuello de botella es el uso, no el contexto
Durante la primera ola de adopción de copilotos, la pregunta dominante fue de ingesta: cómo darle al modelo todo el contexto que necesita. Cargá el repo. Cargá los ADRs. Cargá los tickets. Indexá la documentación. Si el modelo tiene acceso a la información correcta, va a producir respuestas correctas.
Esa hipótesis empezó a mostrarse incompleta.
Recientemente, Seth Canfield publicó CAG-Bench, un benchmark sobre cómo distintas estrategias de memoria sostienen contexto a lo largo de 30 tareas de desarrollo de software encadenadas. El estudio comparó tres enfoques: RAG, basado en recuperación clásica de documentos; DAG, basado en una generación guiada por un flujo fijo de trabajo; y CAG, Context Accumulation Generation, donde decisiones validadas del proyecto se incorporan a una memoria persistente. El modelo bajo prueba fue qwen2.5-coder 7B, un modelo local pequeño. Es una elección metodológica acotada, declarada por el autor, y vale tenerla presente: los números no se trasladan automáticamente a frontier models en producción.
Pero el patrón pide atención.
El hallazgo central, en sus propias palabras: “memory uptake —not merely memory retrieval— is a central bottleneck”. El “a” es deliberado. No “el” único, no “el” universal. Un cuello de botella central, entre otros.
Los números de continuidad lo ilustran. CAG alcanzó 54.2% de recall de continuidad. RAG, 17.1%. DAG, 17.0%. La brecha no parece estar solo en si el modelo encuentra contexto. Está, cada vez más, en si ese contexto logra actuar.
Para diagnosticar el fenómeno, Canfield introdujo una métrica que vale nombrar: memory_usage_rate. La describe, en sus propias palabras, como “the memory_usage_rate metric that separates retrieval failure from uptake failure”. No mide cuánto se recuperó: mide si lo recuperado dejó una huella observable en la respuesta. La huella puede ser superficial; un ADR mencionado pero no aplicado también la deja. Pero la distinción que la métrica abre es útil: una cosa es traer contexto, otra es que ese contexto aparezca en la salida. El hecho de que el autor sintiera la necesidad de nombrar esa distinción ya dice algo: hasta ahora medíamos retrieval y asumíamos uptake.
Recuperar no es usar. Ingerir no es usar.
Y si esto se observa bajo condiciones controladas con un modelo chico, conviene preguntarse cómo se ve el fenómeno bajo condiciones no controladas, con modelos más grandes, en producción real, con presión de timeline. La intuición de quien viene trabajando con copilotos sugiere que el patrón persiste, aunque la magnitud cambie.
Code review como ceremonia de uptake humano
La trampa de pensar este problema como nuevo es que ya lo habíamos visto, solo que con otros actores.
Los humanos también fallamos en uptake. Un equipo puede tener un ADR escrito, accesible, indexado, y aun así proponer una solución que lo contradice. No por descuido: el desarrollo ocurre bajo presión, con información incompleta, con incentivos cruzados y con sistemas que cambian más rápido que sus documentos. La memoria está disponible, pero no siempre aparece en el momento de decidir. La decisión existe, pero no siempre se conecta con la tarea actual.
Por eso evolucionamos algo que a veces tratamos como obvio pero no lo es: el code review.
En su mejor versión, el code review nunca fue solo una cacería de bugs. Los tests cubren parte de esa función. El review humano hace algo más difícil de automatizar: lee la propuesta y verifica que considera el sistema, las decisiones vigentes, las restricciones, la coherencia con el resto. Es una verificación de uptake. La pregunta implícita no es solo “¿este código funciona?”, sino “¿este código fue propuesto por alguien que tuvo en cuenta lo que tenía que tener en cuenta?”.
Esa ceremonia funciona porque introduce un actor distinto del que produjo el código. Uno escribe, otro lee. Uno propone, otro verifica. La separación es estructural, no estética. Si el mismo desarrollador escribiera el código y firmara el review, no habría review. Habría una declaración.
Cuando incorporamos copilotos al sistema, el code review siguió ahí. Pero su carga cambió. Antes verificábamos uptake humano. Ahora verificamos uptake humano más uptake del copiloto, con la misma ceremonia y la misma cantidad de tiempo. La presión por velocidad empuja a confiar en lo que el copiloto produjo. Y la fluidez aparente de su salida invita a creer que consideró lo que tenía que considerar.
El caso del SQLAlchemy ilustra el punto. El code review puede aprobar un código bien escrito que viola una decisión vigente, simplemente porque la decisión no aparece en pantalla cuando se está revisando el diff. La ceremonia humana fue diseñada para una época donde el productor era un humano que también podía recordar. Ahora hay un productor que no recuerda como recuerda un humano, y el verificador es el mismo humano que antes asumía cierta memoria del autor.
Cómo falla el uptake
Vale ser preciso sobre las formas en que un copiloto puede fallar el uptake. No todas las fallas son iguales, y no todas se atrapan con la misma ceremonia.
- Recuperado pero no usado. El contexto correcto fue traído al prompt, pero el modelo no lo incorporó en la respuesta. Es la falla más visible cuando se inspeccionan logs, y la que el paper de Canfield mide directamente.
- Mencionado pero no aplicado. El modelo cita el ADR, lo nombra, demuestra que lo “vio”, pero su propuesta lo ignora. Es una de las más engañosas, porque el output parece reflexionado.
- Aplicado superficialmente. El modelo respeta la letra de la decisión pero no su intención. Por ejemplo, ante un ADR que prescribe acceso a datos por capa de repositorio, crea una clase de repositorio que internamente ejecuta SQL plano: cumple la forma y rompe el principio que el ADR estaba protegiendo.
- Contradicho en silencio. El modelo introduce un cambio que viola la decisión sin nombrarla, sin reconocer que existe, sin sugerir que valga la pena revisarla. Es la falla del caso SQLAlchemy. Y es la más peligrosa, porque produce código que parece bien razonado y porque consume el capital de credibilidad del copiloto: si un cambio plausible pasa, los próximos se revisarán con menos cuidado.
Las cuatro pueden ocurrir con frontier models, no solo con modelos locales pequeños. Lo que cambia con la potencia del modelo es la fluidez de la salida, no la garantía del uptake.
Hutchins: la memoria como práctica, no como archivo
En 1995, Edwin Hutchins publicó Cognition in the Wild, un libro raro: un estudio etnográfico de la navegación de barcos de guerra estadounidenses. La tesis central de Hutchins era que la cognición no vive en una cabeza. Vive distribuida: entre las personas de la tripulación, los instrumentos, las cartas náuticas, los procedimientos, el lenguaje técnico, los rituales de comunicación. Entender cómo un barco navega no es entender la mente del navegante. Es entender el sistema cognitivo completo del que esa mente forma parte.
El argumento que importa acá es uno casi colateral. Un instrumento no es cognitivo por sí mismo. Una carta náutica no es navegación. Una libreta de bitácora no es memoria de la travesía. Solo cuando esos artefactos están entrelazados con la práctica, invocados en el momento correcto, leídos por quien sabe leerlos, integrados en la decisión, se vuelven cognición distribuida.
Trasladado al desarrollo de software: un ADR no es memoria organizacional hasta que participa en el sistema cognitivo en el momento de decidir. Un postmortem no es aprendizaje hasta que cambia una práctica. Un runbook no es operación hasta que guía una respuesta bajo presión. La existencia del artefacto es condición necesaria, no suficiente.
Hutchins explica por qué el code review funcionó como ceremonia de uptake durante décadas, y la “documentación detallada” no. El review es una práctica que fuerza la invocación del artefacto en el momento correcto. La documentación, sin práctica que la invoque, es archivo.
Y eso reordena la pregunta. La conversación sobre cómo darle más contexto al copiloto trata al artefacto como si fuera autosuficiente: si está en el prompt, está usado. Hutchins sugiere lo contrario. Lo que hace que un artefacto sea cognitivo es la práctica que lo invoca. Sin esa práctica, podemos cargar el repositorio entero al contexto y aun así operar con un sistema que no recuerda.
Hacia una ceremonia de uptake para inteligencia mixta
Una aclaración antes de avanzar: uso “ceremonia” no en el sentido burocrático que a veces hereda de la jerga ágil, sino en el sentido fuerte. Una ceremonia es una práctica repetible que obliga a que algo importante ocurra. El code review es ceremonia. La revisión arquitectónica es ceremonia. El postmortem honesto es ceremonia. No son rituales vacíos; son las prácticas que, repetidas en el tiempo, generan hábito, conducta colectiva y atención compartida sobre lo que importa.
Si el code review fue la ceremonia que evolucionamos para verificar uptake humano, ¿cuál es la ceremonia equivalente para una práctica donde un copiloto produce y un humano firma?
No tengo una respuesta cerrada. Pero hay tres movimientos que están emergiendo y que vale evaluar:
- Pre-prompt: pedirle al agente que liste decisiones relevantes antes de proponer. La idea es introducir una pausa cognitiva. Antes de generar la solución, el agente recupera y enumera qué decisiones vigentes considera aplicables al cambio. Si menciona el ADR del ORM, entra al razonamiento. Si no lo menciona, queda registrado que no apareció. Es barato y educativo, pero frágil: depende de que el agente recupere lo correcto y reconozca su relevancia. Es un primer paso, no una solución.
- Post-prompt en PR: declarar qué decisiones se consideraron, respetaron o contradicen. Cada propuesta de cambio incluye una sección estructurada donde el copiloto, o el humano que firma, declara explícitamente: estos ADRs aplican, este los respeta, este los contradice y propone reemplazar X, este los modifica y propone un ADR nuevo. La ceremonia es similar al test plan que muchos equipos exigen, pero apuntada a uptake en vez de a cobertura. La ausencia de declaración es señal: si nadie listó las decisiones afectadas, la propuesta no está lista para revisión.
- Dos agentes: separar generación de revisión. Esta es la más interesante. Un agente genera la propuesta. Otro agente, con un prompt distinto, contexto distinto y posiblemente modelo distinto, revisa la propuesta contra los ADRs, las decisiones vigentes, los principios arquitectónicos. La separación rompe una circularidad que vale nombrar: pedirle al mismo modelo que escribió el código que también lo evalúe es como pedirle al estudiante que escriba el examen y lo corrija. El reviewer no es el verificador final, sigue siendo el humano. Pero introduce una presencia adversarial entre la propuesta y el merge, sin requerir un humano por cada decisión. El costo marginal es bajo, el efecto estructural es alto, y es una ceremonia que escala con la velocidad del copiloto en vez de competir con ella.
Hay una trampa en la tercera que conviene nombrar: dos agentes no son automáticamente dos criterios. Si comparten modelo, contexto e instrucciones implícitas, pueden compartir ceguera. La separación útil no es solo técnica, es epistémica: el revisor necesita otro mandato, otro contexto, idealmente otra familia de modelo. Sin esa diferenciación, lo que parece independencia es eco. La circularidad no se rompe por dividir en dos roles, se rompe por introducir un actor con otra mirada.
Las tres son experimentables hoy, con las herramientas existentes. Ninguna resuelve el problema sola. Combinadas con el code review humano que ya tenemos, empiezan a parecerse a una arquitectura de uptake para inteligencia mixta.
Verificar no es desconfiar
Una resistencia previsible a estas ceremonias: agregan fricción. El copiloto se vendió como herramienta de velocidad, y cualquier ceremonia adicional parece traicionar esa promesa.
La objeción confunde dos cosas. La fricción que protege calidad no es la misma que la fricción que sobra. El code review siempre agregó fricción, y nadie serio propone eliminarlo en nombre de la velocidad. La ceremonia de uptake para inteligencia mixta es del mismo orden: fricción intencional que protege algo que importa más que el tiempo que cuesta.
Hay otra forma de leerlo, más cercana a la idea de simbiosis que aparece desde Licklider en adelante. El copiloto trae lo que trae bien: velocidad, exploración, recuperación, generación a escala. El humano trae lo que el copiloto no puede traer: criterio situado, responsabilidad, comprensión del contexto organizacional, capacidad de decir “esto contradice algo que decidimos por razones que vos no podés ver”. Pretender que un solo actor haga las dos cosas baja el techo del sistema. La ceremonia es lo que mantiene los dos en juego.
Man-in-the-loop, en esta lectura, no es burocracia ni concesión a la prudencia. Es la infraestructura que aprovecha lo mejor de cada actor. Sin esa infraestructura, el copiloto opera con velocidad pero sin uptake, y el humano firma sin haber verificado lo que firmaba.
El error es pensar que la verificación es desconfianza. Verificar es la forma técnica que toma la confianza cuando hay dos actores con perfiles distintos de fortaleza y debilidad. Confiamos lo suficiente en el copiloto para dejarlo proponer. Confiamos lo suficiente en nosotros para verificar. El equilibrio es lo que sostiene la simbiosis.
El ADR de SQLAlchemy no estaba ausente. Tampoco era irrecuperable. Lo que falló fue la estructura que debía hacerlo actuar: la misma unidad humano-copiloto produjo y verificó, en un proyecto chico que cabía en una sola lectura. Funcionó por circunstancia, no por diseño.
La conversación sobre cómo darle más contexto al copiloto puede continuar, y va a continuar. Pero la pregunta que aparece detrás, y que el paper de Canfield empezó a darle nombre, es de otro orden. No es cuánta memoria le damos. Es cómo verificamos que esa memoria efectivamente actuó. La práctica que invoca al artefacto es lo que lo vuelve cognitivo.
Eso desplaza el trabajo de ingeniería de la era del copiloto en una dirección poco explorada. No alcanza con producir más artefactos. Hay que diseñar las ceremonias que los vuelven cognitivos. Code review fue la ceremonia que aprendimos a nombrar. Habrá más.
¿Qué ceremonias nuevas estás viendo emerger en tu equipo para verificar que el contexto efectivamente actúa?
Referencias
- Canfield, S. (2026). Benchmarking Persistent Project Memory in Local Language Models: CAG vs RAG vs DAG over 30 Sequential Tasks. Guideboard Labs. https://zenodo.org/records/19979272
- Hutchins, E. (1995). Cognition in the Wild. MIT Press.