Spring til indhold
cd /blog

At mine løkken: Sådan bliver ændringer til institutionel hukommelse

[Arkitektur][Arbejdsgange]

> Git-commits bliver til strukturerede changelog-poster og arkitektoniske beslutningsregistreringer, som derefter fødes tilbage til AI-agenter som forespørgelig institutionel hukommelse.

Tallene i dette indlæg afspejler systemet på udgivelsestidspunktet (februar 2026). Se vores team-side for aktuelle tal.

Ethvert engineering-team står over for den samme udfordring: ændringer sker konstant, men hvorfor’et bag de ændringer forsvinder. Seks måneder senere spørger nogen “hvorfor adopterede vi DuckDB til pipeline-stadier?”, og svaret lever kun i hovedet på den, der traf det valg — hvis vedkommende stadig er her.

Vi byggede en mining-arbejdsgang, der lukker denne løkke. Ændringer flyder gennem git-commits, bliver behandlet af vores mining-pipeline, bliver til strukturerede changelog-poster og arkitektoniske beslutningsregistreringer, og fødes derefter tilbage til vores AI-agenter gennem CLI-forespørgsler. Resultatet: institutionel hukommelse, som både mennesker og AI kan tilgå.

Problemet: Beslutninger fordamper

Overvej et typisk scenarie. En udvikler committer:

feat(canonical): add DuckDB runtime for pipeline stages

Denne commit repræsenterer et betydeligt arkitektonisk valg. Teamet evaluerede muligheder, overvejede afvejninger og landede på DuckDB af specifikke årsager. Men al den kontekst lever i:

  • En Slack-tråd (sandsynligvis slettet)
  • Nogens hukommelse (bestemt falmende)
  • En kommentar i koden (måske, hvis man er heldig)

Tre måneder senere spørger et nyt teammedlem: “Skal jeg bruge DuckDB eller SQLite til dette nye stadie?” Uden institutionel hukommelse genopfinder de enten den dybe tallerken eller træffer inkonsistente valg.

Løkken: Fra commits til kontekst

Vores mining-arbejdsgang omdanner git-historik til forespørgelig viden:

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

Den centrale indsigt: både changelogs og arkitektoniske beslutninger flyder fra den samme git-historik, behandlet gennem en samlet pipeline. Det sikrer, at intet falder mellem to stole.

Sådan fungerer mining

Trin 1: Synkronisér indekset

uv run orkestra mine sync

Denne kommando skanner git-historik og bygger et indeks over alle commits. Den udtrækker strukturerede signaler fra hver commit:

  • Konventionel commit-type (feat, fix, chore, docs)
  • Scope (hvilken pakke eller område)
  • Breaking-change-markører
  • Berørte filer og kompleksitetsmetrikker

Trin 2: Tjek dækningsstatus

uv run orkestra mine status

Sådan ser vores nuværende status ud:

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 behandlet. 476 blev til arkitektoniske beslutninger. 6.799 blev til changelog-poster. Hver commit klassificeret.

Trin 3: Hent kandidater til gennemgang

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

Dette fremviser commits, der endnu ikke er blevet behandlet, med fuld kontekst til klassificering:

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

Signalerne hjælper med at guide klassificeringen: is_releasable_type: true antyder, at denne bør fremgå af changelog’en. Det store antal indsættelser og infrastrukturfilerne antyder, at den også kunne være en arkitektonisk beslutning.

Trin 4: Klassificér commits

To stier deler sig her: changelog-poster og arkitektoniske beslutninger.

For changelog-poster:

uv run orkestra mine classify abc123 --changelog added

Dette registrerer, at commit abc123 bør fremgå af changelog’en under kategorien “Added.”

For arkitektoniske beslutninger:

Først, hent et reelt beslutnings-ID:

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

Klassificér derefter med beslutnings-ID’et:

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

Dette knytter commit’en til en beslutningsregistrering, der vil blive oprettet eller opdateret.

For batch-behandling (det, vi rent faktisk gør):

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

JSONL-formatet understøtter begge domæner i én omgang:

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

Trin 5: Render outputs

uv run orkestra changelog render --package <pkg>

Dette genererer CHANGELOG.md-filer pr. pakke ud fra ledgeren. Changelogs er afledte artefakter — slet dem, og de genereres perfekt igen fra kilde-ledgeren.

Beslutningsregistreringens struktur

Udtrukne beslutninger bliver til YAML-filer med rig metadata:

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

Hver beslutning linker tilbage til sine kilde-commits. Hver beslutning angiver, hvilke filer den påvirker. Relationer mellem beslutninger er eksplicitte.

CLI-integration: Forespørgsel på institutionel hukommelse

Det er her, løkken lukkes. Agenter kan forespørge beslutninger gennem CLI’en:

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

Returnerer beslutninger om retry-logik, fejlhåndtering, recovery-mønstre.

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

Returnerer den komplette beslutningsregistrering med kontekst, begrundelse og konsekvens.

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

Viser hvilke arkitektoniske valg der blev truffet for nylig.

Sådan bruger agenter dette

Vores orkestrators grundlæggende instruktioner inkluderer:

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

Når en agent bliver bedt om at implementere noget relateret til DuckDB, kan den først tjekke:

uv run orkestra decisions search --query "DuckDB"

Og opdage DEC-PL-142, og lære:

  • Hvorfor vi valgte DuckDB (context)
  • Hvordan man bruger det korrekt (agent_guidance)
  • Hvilke filer man skal kigge på (files)
  • Hvilke relaterede beslutninger der findes (related)

Agenten genopfinder ikke den dybe tallerken. Den bygger videre på etablerede mønstre.

De tre spørgsmåls test

Ikke enhver commit fortjener en beslutningsregistrering. Vi bruger de tre spørgsmåls test til at filtrere:

  1. Var dette svært at træffe? Krævede det betydelig analyse, afvejningsvurdering eller debat?
  2. Er det dyrt at ændre? Ville det kræve betydeligt genarbejde at omgøre denne beslutning?
  3. Har det systemomfattende konsekvens? Påvirker det flere pakker eller etablerer det mønstre, andre vil følge?

Hvis en commit svarer “ja” på mindst ét af disse spørgsmål, er den kandidat til beslutningsudtræk. Vores typiske rate: 1-4 beslutninger pr. 100 commits (omkring 1-4%).

For changelog-poster er barren lavere: enhver brugervendt ændring (features, fixes, forbedringer) registreres. Interne opgaver, dokumentationsopdateringer og refaktoreringer springes typisk over. Vores typiske rate: 30-50 changelog-poster pr. 100 commits.

Datalagring: Append-only ledgers

Mining-systemet bruger append-only JSONL-ledgers til konfliktfri multi-agent-drift:

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

JSONL-formatet med merge=union i .gitattributes betyder, at flere agenter kan klassificere commits samtidigt uden merge-konflikter. Hver linje er uafhængig.

Valideringsgates

Før enhver mining-session kører vi validering:

uv run orkestra mine validate --quick

Dette tjekker:

  • Gyldighed af SHA-format
  • Overholdelse af beslutnings-ID-format
  • Ingen dubletregistreringer for den samme SHA
  • At refererede beslutninger rent faktisk findes

Efter klassificering validerer vi igen, før vi committer ændringerne.

Hvorfor det betyder noget

Den feedbackløkke, vi har bygget, løser flere problemer:

For nye teammedlemmer: I stedet for at spørge “hvorfor gjorde vi X?”, kan de søge i beslutningsregistret. Konteksten er bevaret.

For AI-agenter: De opererer ikke i et vakuum. De kan forespørge institutionel viden, før de kommer med anbefalinger. Når de bliver bedt om at tilføje et nyt pipeline-stadie, kan de opdage DuckDB-mønsteret og følge det.

For arkitektonisk konsistens: Beslutninger er eksplicitte og søgbare. Når nogen foreslår en tilgang, der modsiger en eksisterende beslutning, kan systemet fremhæve konflikten.

For changelog-generering: Release notes er ikke en sidste-øjebliks-hastværk. De er et biprodukt af løbende klassificering under udvikling.

For onboarding: Nye agenter arver hele kodebasens kontekst. De ser ikke bare koden — de ser de beslutninger, der formede den.

Nuværende tilstand

Pr. i dag:

  • 15.637 commits behandlet gennem pipelinen
  • 476 arkitektoniske beslutninger udtrukket og dokumenteret
  • 6.799 changelog-poster registreret
  • 100% dækning på tværs af begge domæner

Hver commit siden vi startede, er blevet klassificeret. Den institutionelle hukommelse er komplet og forespørgelig.

Kom i gang

Hvis du vil implementere noget lignende:

  1. Start med konventionelle commits. Mining-pipelinen fungerer bedst, når commits har strukturerede præfikser (feat:, fix:, chore:).

  2. Definér dine domæner. Vi bruger domæner som pipeline, agent-design, observability, data-modeling. Disse organiserer beslutninger efter område.

  3. Byg klassificeringsvanen op. Mining fungerer, når teams regelmæssigt klassificerer commits. Batch-behandling med LLM-assistance hjælper med at skalere.

  4. Gør beslutninger forespørgelige. Værdien kompoundes, når agenter kan søge i beslutninger via CLI. Strukturér dit output til maskinkonsum.

  5. Luk løkken. Beslutninger bør påvirke fremtidigt arbejde. Inkludér beslutningsreferencer i agentinstruktioner og code review-tjeklister.

Målet er ikke perfekt dokumentation. Det er at gøre hvorfor’et bag ændringer tilgængeligt for både mennesker og AI, i dag og seks måneder fra nu. Når ændringer bliver institutionel hukommelse, bygger teams videre på etablerede mønstre i stedet for at genopfinde dem.


Mining-arbejdsgangen er en del af vores orkestreringsmotor, specifikt context-motor-modulet i vores orchestration-pakke.

Relateret læsning

Mere fra Maguyva-byggeloggen