Minando el bucle: cómo los cambios se convierten en memoria institucional
> Los commits de Git se convierten en entradas de changelog estructuradas y registros de decisiones arquitectónicas, que luego retroalimentan a los agentes de IA como memoria institucional consultable.
Las cifras de esta publicación reflejan el sistema al momento de su publicación (febrero de 2026). Consulta nuestra página del equipo para ver las cifras actuales.
Todo equipo de ingeniería enfrenta el mismo desafío: los cambios ocurren constantemente, pero el por qué detrás de esos cambios desaparece. Seis meses después, alguien pregunta «¿por qué adoptamos DuckDB para las etapas del pipeline?» y la respuesta solo vive en la cabeza de quien tomó esa decisión, si es que todavía sigue por ahí.
Construimos un flujo de trabajo de minería que cierra este bucle. Los cambios fluyen a través de commits de Git, se procesan mediante nuestro pipeline de minería, se convierten en entradas de changelog estructuradas y registros de decisiones arquitectónicas, y luego retroalimentan a nuestros agentes de IA mediante consultas por CLI. El resultado: memoria institucional a la que tanto humanos como IA pueden acceder.
El problema: las decisiones se evaporan
Considera un escenario típico. Un desarrollador hace commit:
feat(canonical): add DuckDB runtime for pipeline stages
Este commit representa una elección arquitectónica significativa. El equipo evaluó opciones, consideró los compromisos, y se decidió por DuckDB por razones específicas. Pero todo ese contexto vive en:
- Un hilo de Slack (probablemente borrado)
- La memoria de alguien (definitivamente se va desvaneciendo)
- Un comentario en el código (tal vez, si tienes suerte)
Tres meses después, un nuevo integrante del equipo pregunta: «¿debería usar DuckDB o SQLite para esta nueva etapa?». Sin memoria institucional, o reinventa la rueda o toma decisiones inconsistentes.
El bucle: de los commits al contexto
Nuestro flujo de trabajo de minería transforma el historial de Git en conocimiento consultable:
Git Commits
│
▼
┌─────────────────────┐
│ mine sync │ ← Build index from git history
└─────────────────────┘
│
▼
┌─────────────────────┐
│ mine candidates │ ← Surface commits for review
└─────────────────────┘
│
▼
┌─────────────────────┐
│ Classification │ ← Human or LLM assessment
│ (changelog or ADR) │
└─────────────────────┘
│
├──────────────────────┐
▼ ▼
┌─────────────┐ ┌───────────────┐
│ Changelog │ │ Decisions │
│ Ledger │ │ Registry │
│ (JSONL) │ │ (YAML files) │
└─────────────┘ └───────────────┘
│ │
▼ ▼
┌─────────────┐ ┌───────────────┐
│ CHANGELOG.md│ │ orkestra CLI │
│ per package │ │ queries │
└─────────────┘ └───────────────┘
│ │
└──────────────────────┘
│
▼
┌───────────────┐
│ AI Agents │
│ (via CLI) │
└───────────────┘
La idea clave: tanto los changelogs como las decisiones arquitectónicas fluyen del mismo historial de Git, procesado a través de un pipeline unificado. Esto garantiza que nada se escape.
Cómo funciona la minería
Paso 1: sincronizar el índice
uv run orkestra mine sync
Este comando escanea el historial de Git y construye un índice de todos los commits. Extrae señales estructuradas de cada commit:
- Tipo de commit convencional (
feat,fix,chore,docs) - Alcance (qué paquete o área)
- Marcadores de cambios disruptivos
- Archivos tocados y métricas de complejidad
Paso 2: verificar el estado de cobertura
uv run orkestra mine status
Así se ve nuestro estado actual:
Mining Status
=============
Decisions
---------
Coverage: 100.0%
Processed: 15637 (of 15637)
Extracted: 476
Skipped: 15161
Changelog
---------
Coverage: 100.0%
Processed: 15637 (of 15637)
Released: 6799
Skipped: 8838
15,637 commits procesados. 476 se convirtieron en decisiones arquitectónicas. 6,799 se convirtieron en entradas de changelog. Cada commit está clasificado.
Paso 3: obtener candidatos para revisión
uv run orkestra mine candidates --limit 50 --full
Esto muestra los commits que todavía no se han procesado, con el contexto completo para su clasificación:
on
{
"sha": "90571786d99166c0039ca2e80e4d9cd96184bd85",
"date": "2026-01-26",
"subject": "feat(canonical): add DuckDB runtime for pipeline stages",
"signals": {
"commit_type": "feat",
"scope": "canonical",
"breaking": false,
"is_releasable_type": true,
"domains_affected": ["pipeline", "data-architecture"]
},
"body": "Establishes DuckDB as canonical in-process analytical database...",
"files_changed": ["packages/canonical/pipelines/stages/duckdb_runtime.py", "..."],
"stats": {"files": 8, "insertions": 450, "deletions": 120}
}
Las señales ayudan a guiar la clasificación: is_releasable_type: true sugiere que esto debería aparecer en el changelog. El gran número de inserciones y los archivos de infraestructura sugieren que también podría ser una decisión arquitectónica.
Paso 4: clasificar commits
Aquí se bifurcan dos caminos: entradas de changelog y decisiones arquitectónicas.
Para entradas de changelog:
uv run orkestra mine classify abc123 --changelog added
Esto registra que el commit abc123 debería aparecer en el changelog bajo la categoría «Added».
Para decisiones arquitectónicas:
Primero, obtén un ID de decisión real:
uv run orkestra decisions new --domain pipeline --dry-run
# Returns: DEC-PL-143
Luego clasifica con el ID de decisión:
uv run orkestra mine classify abc123 --decision DEC-PL-143
Esto vincula el commit a un registro de decisión que se creará o actualizará.
Para procesamiento por lotes (lo que en realidad hacemos):
# Generate classifications file with LLM assistance
uv run orkestra mine commit --input classifications.jsonl
El formato JSONL admite ambos dominios en una sola pasada:
on
l
{"sha":"abc123","domain":"changelog","action":"release","category":"added","summary":"Add DuckDB runtime for pipeline stages"}
{"sha":"abc123","domain":"decisions","action":"extract","decision_id":"DEC-PL-142"}
{"sha":"def456","domain":"changelog","action":"skip","reason":"Chore: dependency update"}
Paso 5: renderizar las salidas
uv run orkestra changelog render --package <pkg>
Esto genera archivos CHANGELOG.md por paquete a partir del ledger. Los changelogs son artefactos derivados: bórralos y se regeneran perfectamente a partir del ledger fuente.
La estructura del registro de decisiones
Las decisiones extraídas se convierten en archivos YAML con metadatos ricos:
id: DEC-PL-142
title: Adopt DuckDB as Canonical Processing Runtime for Pipeline Stages
domain: pipeline
status: active
created: '2026-01-26'
summary: |
Establishes DuckDB as the canonical in-process analytical database for pipeline
stage transformations. Provides a shared runtime module that resolves settings
from pipeline defaults with stage-level overrides.
context: |
Pipeline stages performing data transformations each independently configured
DuckDB connections. This led to inconsistent settings, duplicated configuration
code, and no way to tune DuckDB globally for a pipeline run.
rationale:
- DuckDB provides efficient in-process OLAP with zero configuration deployment
- Centralized runtime module eliminates duplicated DuckDB setup across stages
- Hierarchical settings enable global tuning with stage-level overrides
- Memory limits and thread counts can be adjusted per-pipeline
impact:
positive:
- Consistent DuckDB configuration across all pipeline stages
- Single point of control for memory/thread tuning
- Reduced code duplication in conversion and export stages
negative:
- Adds dependency on shared runtime module
- Stages must adopt new configuration pattern
source_commits:
- sha: 90571786d99166c0039ca2e80e4d9cd96184bd85
message: 'feat(canonical): add DuckDB runtime for pipeline stages'
date: '2026-01-26'
role: primary
files:
- packages/canonical/pipelines/stages/duckdb_runtime.py
- packages/canonical/pipelines/runner.py
- packages/canonical/pipelines/stages/convert_hdx_admin_boundaries_to_geoparquet.py
related:
- DEC-DA-014 # Data architecture decisions that influenced this
Cada decisión enlaza de vuelta a sus commits de origen. Cada decisión especifica qué archivos afecta. Las relaciones entre decisiones son explícitas.
Integración con la CLI: consultando la memoria institucional
Aquí es donde se cierra el bucle. Los agentes pueden consultar decisiones a través de la CLI:
# Search by topic
uv run orkestra decisions search --query "retry"
Devuelve decisiones sobre lógica de reintento, manejo de errores, patrones de recuperación.
# Get full details on a specific decision
uv run orkestra decisions info DEC-PL-142
Devuelve el registro de decisión completo con contexto, justificación e impacto.
# List recent decisions for context
uv run orkestra decisions list --limit 15
Muestra qué elecciones arquitectónicas se tomaron recientemente.
Cómo usan esto los agentes
Las instrucciones base de nuestro orquestador incluyen:
**Essential CLI commands:**
- `orkestra decisions search "X"` — Find architectural decisions
Cuando se le pide a un agente que implemente algo relacionado con DuckDB, primero puede verificar:
uv run orkestra decisions search --query "DuckDB"
Y descubrir DEC-PL-142, aprendiendo:
- Por qué elegimos DuckDB (context)
- Cómo usarlo correctamente (agent_guidance)
- Qué archivos revisar (files)
- Qué decisiones relacionadas existen (related)
El agente no reinventa la rueda. Construye sobre patrones ya establecidos.
La prueba de las tres preguntas
No todo commit merece un registro de decisión. Usamos la prueba de las tres preguntas para filtrar:
- ¿Fue difícil de tomar? ¿Requirió un análisis significativo, evaluación de compromisos o debate?
- ¿Es costoso de cambiar? ¿Revertir esta decisión requeriría un retrabajo significativo?
- ¿Tiene impacto en todo el sistema? ¿Afecta a varios paquetes o establece patrones que otros seguirán?
Si un commit responde «sí» a al menos una de estas preguntas, es candidato para la extracción de una decisión. Nuestra tasa típica: 1-4 decisiones por cada 100 commits (alrededor del 1-4%).
Para las entradas de changelog, el umbral es más bajo: cualquier cambio visible para el usuario (funciones, correcciones, mejoras) se registra. Las tareas internas, las actualizaciones de documentación y las refactorizaciones normalmente se omiten. Nuestra tasa típica: 30-50 entradas de changelog por cada 100 commits.
Almacenamiento de datos: ledgers de solo anexado
El sistema de minería usa ledgers JSONL de solo anexado para una operación multiagente sin conflictos:
packages/orchestration/ai_assets/reference/changelog/
├── commits_processed.jsonl # Classification ledger (both domains)
├── release_notes.jsonl # Changelog entries
└── commits_index.yaml # Derived index (gitignored)
packages/orchestration/ai_assets/reference/decisions/
├── registry.yaml # Decision index
└── records/
├── DEC-AD-001.yaml
├── DEC-AD-002.yaml
└── ...
El formato JSONL con merge=union en .gitattributes significa que varios agentes pueden clasificar commits simultáneamente sin conflictos de fusión. Cada línea es independiente.
Compuertas de validación
Antes de cualquier sesión de minería, ejecutamos una validación:
uv run orkestra mine validate --quick
Esto verifica:
- Validez del formato del SHA
- Cumplimiento del formato del ID de decisión
- Ausencia de entradas duplicadas para el mismo SHA
- Que las decisiones referenciadas realmente existan
Después de la clasificación, validamos de nuevo antes de hacer commit de los cambios.
Por qué esto importa
El bucle de retroalimentación que construimos resuelve varios problemas:
Para nuevos integrantes del equipo: en lugar de preguntar «¿por qué hicimos X?», pueden buscar en el registro de decisiones. El contexto se conserva.
Para los agentes de IA: no operan en el vacío. Pueden consultar el conocimiento institucional antes de hacer recomendaciones. Cuando se les pide agregar una nueva etapa al pipeline, pueden descubrir el patrón de DuckDB y seguirlo.
Para la consistencia arquitectónica: las decisiones son explícitas y consultables. Cuando alguien propone un enfoque que contradice una decisión existente, el sistema puede sacar a la luz el conflicto.
Para la generación del changelog: las notas de la versión no son una carrera de último minuto. Son un subproducto de la clasificación continua durante el desarrollo.
Para la incorporación de nuevos integrantes: los nuevos agentes heredan el contexto completo de la base de código. No solo ven el código, ven las decisiones que lo formaron.
Estado actual
A la fecha:
- 15,637 commits procesados a través del pipeline
- 476 decisiones arquitectónicas extraídas y documentadas
- 6,799 entradas de changelog registradas
- 100% de cobertura en ambos dominios
Cada commit desde que empezamos ha sido clasificado. La memoria institucional está completa y es consultable.
Cómo empezar
Si quieres implementar algo similar:
-
Empieza con commits convencionales. El pipeline de minería funciona mejor cuando los commits tienen prefijos estructurados (
feat:,fix:,chore:). -
Define tus dominios. Nosotros usamos dominios como
pipeline,agent-design,observability,data-modeling. Estos organizan las decisiones por área. -
Construye el hábito de la clasificación. La minería funciona cuando los equipos clasifican commits regularmente. El procesamiento por lotes con asistencia de LLM ayuda a escalar.
-
Haz que las decisiones sean consultables. El valor se multiplica cuando los agentes pueden buscar decisiones vía CLI. Estructura tu salida para consumo por máquinas.
-
Cierra el bucle. Las decisiones deberían influir en el trabajo futuro. Incluye referencias a decisiones en las instrucciones de los agentes y en las listas de verificación de revisión de código.
El objetivo no es una documentación perfecta. Es hacer que el por qué detrás de los cambios sea accesible tanto para humanos como para IA, hoy y dentro de seis meses. Cuando los cambios se convierten en memoria institucional, los equipos construyen sobre patrones establecidos en lugar de reinventarlos.
El flujo de trabajo de minería es parte de nuestro motor de orquestación, específicamente el módulo de motor de contexto dentro de nuestro paquete de orquestación.
Lectura relacionada
Más del registro de build de Maguyva
Por qué actualizamos la búsqueda de código a voyage-4-large_
Migramos nuestros embeddings de código a voyage-4-large — actualmente en la cima de la tabla pública de RTEB para recuperación de código. La versión honesta: el compromiso que hacemos, qué indexamos realmente, y por qué pagamos por embeddings premium.
Autosuperación recursiva de lenguajes: afinando la inteligencia de código en ~280 lenguajes_
Damos soporte de inteligencia de código para ~280 lenguajes. Ningún humano puede auditar eso a mano. Así que construimos un bucle de autosuperación recursiva de lenguajes — verificación puntual, LLM como juez, corregir una cosa, revalidar — y lo ejecutamos con una flota de agentes aislados hasta que la extracción sea realmente correcta, no solo verde.
Búsqueda por fusión multimodal: eligiendo el recuperador correcto para cada consulta_
Una consulta como 'dónde está definido parseConfig' necesita una búsqueda distinta a 'cómo funciona la autenticación'. Maguyva clasifica la intención, pondera en consecuencia cuatro modalidades de recuperación, y fusiona los resultados con Reciprocal Rank Fusion ponderada.