Passer au contenu
cd /blog

Miner la boucle : comment les changements deviennent mémoire institutionnelle

[Architecture][Workflows]

> Les commits Git deviennent des entrées de changelog structurées et des fiches de décision architecturale, puis reviennent nourrir les agents IA sous forme de mémoire institutionnelle interrogeable.

Les chiffres de cet article reflètent le système au moment de la publication (février 2026). Consultez notre page équipe pour les chiffres actuels.

Chaque équipe d’ingénierie fait face au même défi : les changements se produisent en continu, mais le pourquoi derrière ces changements disparaît. Six mois plus tard, quelqu’un demande « pourquoi avons-nous adopté DuckDB pour les étapes du pipeline ? », et la réponse ne vit que dans la tête de la personne qui a pris cette décision — si elle est encore là.

Nous avons construit un flux de travail de minage qui referme cette boucle. Les changements transitent par les commits Git, sont traités par notre pipeline de minage, deviennent des entrées de changelog structurées et des fiches de décision architecturale, puis reviennent nourrir nos agents IA via des requêtes en ligne de commande. Le résultat : une mémoire institutionnelle accessible aussi bien aux humains qu’à l’IA.

Le problème : les décisions s’évaporent

Considérez un scénario typique. Un développeur commite :

feat(canonical): add DuckDB runtime for pipeline stages

Ce commit représente un choix architectural significatif. L’équipe a évalué des options, pesé des compromis, et opté pour DuckDB pour des raisons précises. Mais tout ce contexte vit dans :

  • Un fil Slack (probablement supprimé)
  • La mémoire de quelqu’un (qui s’estompe assurément)
  • Un commentaire dans le code (peut-être, si vous avez de la chance)

Trois mois plus tard, un nouveau membre de l’équipe demande : « Dois-je utiliser DuckDB ou SQLite pour cette nouvelle étape ? » Sans mémoire institutionnelle, il réinvente la roue ou fait des choix incohérents.

La boucle : des commits au contexte

Notre flux de travail de minage transforme l’historique Git en savoir interrogeable :

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)     │
      └───────────────┘

L’idée clé : les entrées de changelog et les décisions architecturales découlent toutes deux du même historique Git, traité par un pipeline unifié. Cela garantit que rien ne passe entre les mailles du filet.

Comment fonctionne le minage

Étape 1 : synchroniser l’index

uv run orkestra mine sync

Cette commande scanne l’historique Git et construit un index de tous les commits. Elle extrait de chaque commit des signaux structurés :

  • Type de commit conventionnel (feat, fix, chore, docs)
  • Portée (quel package ou quelle zone)
  • Marqueurs de changement cassant
  • Fichiers touchés et métriques de complexité

Étape 2 : vérifier le statut de couverture

uv run orkestra mine status

Voici à quoi ressemble notre statut actuel :

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 traités. 476 sont devenus des décisions architecturales. 6 799 sont devenus des entrées de changelog. Chaque commit est classé.

Étape 3 : obtenir des candidats à relire

uv run orkestra mine candidates --limit 50 --full

Cela fait remonter les commits pas encore traités, avec le contexte complet pour la classification :

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}
}

Les signaux aident à guider la classification : is_releasable_type: true suggère que ceci devrait apparaître dans le changelog. Le grand nombre d’insertions et les fichiers d’infrastructure suggèrent que cela pourrait aussi être une décision architecturale.

Étape 4 : classer les commits

Deux chemins divergent ici : les entrées de changelog et les décisions architecturales.

Pour les entrées de changelog :

uv run orkestra mine classify abc123 --changelog added

Cela enregistre que le commit abc123 doit apparaître dans le changelog sous la catégorie « Ajouté ».

Pour les décisions architecturales :

D’abord, obtenez un véritable identifiant de décision :

uv run orkestra decisions new --domain pipeline --dry-run
# Returns: DEC-PL-143

Puis classez avec cet identifiant de décision :

uv run orkestra mine classify abc123 --decision DEC-PL-143

Cela relie le commit à une fiche de décision qui sera créée ou mise à jour.

Pour le traitement par lots (ce que nous faisons réellement) :

# Generate classifications file with LLM assistance
uv run orkestra mine commit --input classifications.jsonl

Le format JSONL prend en charge les deux domaines en un seul passage :

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"}

Étape 5 : générer les sorties

uv run orkestra changelog render --package <pkg>

Cela génère, à partir du registre, des fichiers CHANGELOG.md par package. Les changelogs sont des artefacts dérivés — supprimez-les, et ils se régénèrent parfaitement à partir du registre source.

La structure d’une fiche de décision

Les décisions extraites deviennent des fichiers YAML dotés de métadonnées riches :

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

Chaque décision renvoie à ses commits sources. Chaque décision précise quels fichiers elle affecte. Les relations entre décisions sont explicites.

Intégration CLI : interroger la mémoire institutionnelle

C’est ici que la boucle se referme. Les agents peuvent interroger les décisions via la CLI :

# Search by topic
uv run orkestra decisions search --query "retry"

Renvoie les décisions liées à la logique de nouvelle tentative, à la gestion des erreurs, aux schémas de récupération.

# Get full details on a specific decision
uv run orkestra decisions info DEC-PL-142

Renvoie la fiche de décision complète, avec contexte, justification et impact.

# List recent decisions for context
uv run orkestra decisions list --limit 15

Montre quels choix architecturaux ont été faits récemment.

Comment les agents utilisent cela

Les instructions de base de notre orchestrateur incluent :

**Essential CLI commands:**
- `orkestra decisions search "X"` — Find architectural decisions

Quand un agent reçoit la demande d’implémenter quelque chose lié à DuckDB, il peut d’abord vérifier :

uv run orkestra decisions search --query "DuckDB"

Et découvrir DEC-PL-142, apprenant ainsi :

  • Pourquoi nous avons choisi DuckDB (context)
  • Comment l’utiliser correctement (agent_guidance)
  • Quels fichiers consulter (files)
  • Quelles décisions connexes existent (related)

L’agent ne réinvente pas la roue. Il s’appuie sur des schémas déjà établis.

Le test des trois questions

Tout commit ne mérite pas une fiche de décision. Nous utilisons le test des trois questions pour filtrer :

  1. Était-ce difficile à décider ? Cela a-t-il exigé une analyse significative, une évaluation de compromis, ou un débat ?
  2. Est-ce coûteux à changer ? Revenir sur cette décision exigerait-il un travail de refonte important ?
  3. A-t-elle un impact à l’échelle du système ? Affecte-t-elle plusieurs packages, ou établit-elle des schémas que d’autres suivront ?

Si un commit répond « oui » à au moins une de ces questions, il est candidat à l’extraction en décision. Notre taux habituel : 1 à 4 décisions pour 100 commits (environ 1 à 4 %).

Pour les entrées de changelog, la barre est plus basse : tout changement visible par l’utilisateur (fonctionnalités, corrections, améliorations) est enregistré. Les tâches internes, les mises à jour de documentation et les refactorisations sont généralement écartées. Notre taux habituel : 30 à 50 entrées de changelog pour 100 commits.

Stockage des données : registres en ajout seul

Le système de minage utilise des registres JSONL en ajout seul, pour un fonctionnement multi-agents sans conflit :

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
    └── ...

Le format JSONL, avec merge=union dans .gitattributes, signifie que plusieurs agents peuvent classer des commits simultanément sans conflit de fusion. Chaque ligne est indépendante.

Portes de validation

Avant toute session de minage, nous exécutons une validation :

uv run orkestra mine validate --quick

Cela vérifie :

  • La validité du format SHA
  • La conformité du format d’identifiant de décision
  • L’absence d’entrées en double pour un même SHA
  • L’existence réelle des décisions référencées

Après la classification, nous validons à nouveau avant de commiter les changements.

Pourquoi cela compte

La boucle de rétroaction que nous avons construite résout plusieurs problèmes :

Pour les nouveaux membres de l’équipe : au lieu de demander « pourquoi avons-nous fait X ? », ils peuvent chercher dans le registre des décisions. Le contexte est préservé.

Pour les agents IA : ils n’opèrent pas dans le vide. Ils peuvent interroger le savoir institutionnel avant de formuler des recommandations. Quand on leur demande d’ajouter une nouvelle étape de pipeline, ils peuvent découvrir le schéma DuckDB et le suivre.

Pour la cohérence architecturale : les décisions sont explicites et interrogeables. Quand quelqu’un propose une approche qui contredit une décision existante, le système peut faire remonter le conflit.

Pour la génération du changelog : les notes de version ne sont pas une course de dernière minute. Elles sont un sous-produit de la classification continue pendant le développement.

Pour l’intégration : les nouveaux agents héritent du contexte complet de la base de code. Ils ne voient pas seulement le code — ils voient les décisions qui l’ont façonné.

État actuel

À ce jour :

  • 15 637 commits traités par le pipeline
  • 476 décisions architecturales extraites et documentées
  • 6 799 entrées de changelog enregistrées
  • 100 % de couverture sur les deux domaines

Chaque commit depuis nos débuts a été classé. La mémoire institutionnelle est complète et interrogeable.

Pour commencer

Si vous voulez implémenter quelque chose de similaire :

  1. Commencez par des commits conventionnels. Le pipeline de minage fonctionne mieux quand les commits ont des préfixes structurés (feat:, fix:, chore:).

  2. Définissez vos domaines. Nous utilisons des domaines comme pipeline, agent-design, observability, data-modeling. Ils organisent les décisions par zone.

  3. Construisez l’habitude de classification. Le minage fonctionne quand les équipes classent régulièrement les commits. Le traitement par lots assisté par LLM aide à passer à l’échelle.

  4. Rendez les décisions interrogeables. La valeur se compose quand les agents peuvent chercher les décisions via la CLI. Structurez votre sortie pour une consommation par machine.

  5. Refermez la boucle. Les décisions doivent influencer le travail futur. Incluez des références aux décisions dans les instructions des agents et les listes de vérification de revue de code.

L’objectif n’est pas une documentation parfaite. C’est de rendre le pourquoi derrière les changements accessible, à la fois aux humains et à l’IA, aujourd’hui comme dans six mois. Quand les changements deviennent mémoire institutionnelle, les équipes construisent sur des schémas établis plutôt que de les réinventer.


Le flux de travail de minage fait partie de notre moteur d’orchestration, plus précisément du module de moteur de contexte de notre package d’orchestration.

Lectures associées

Encore plus du journal de bord Maguyva