Mining av løkken: Hvordan endringer blir institusjonell hukommelse
> Git-commits blir strukturerte endringslogg-oppføringer og arkitekturbeslutningsjournaler, som deretter mates tilbake til AI-agenter som søkbar institusjonell hukommelse.
Tallene i dette innlegget gjenspeiler systemet ved publisering (februar 2026). Se teamsiden for gjeldende tall.
Hvert ingeniørteam møter den samme utfordringen: endringer skjer hele tiden, men hvorfor-et bak de endringene forsvinner. Seks måneder senere spør noen «hvorfor tok vi i bruk DuckDB for pipeline-stadier?», og svaret finnes bare i hodet til den som tok den avgjørelsen — hvis de fortsatt er der.
Vi bygde en mining-arbeidsflyt som lukker denne løkken. Endringer flyter gjennom git-commits, prosesseres av mining-pipelinen vår, blir strukturerte endringslogg-oppføringer og arkitekturbeslutningsjournaler, og mates deretter tilbake til AI-agentene våre gjennom CLI-spørringer. Resultatet: institusjonell hukommelse som både mennesker og AI kan få tilgang til.
Problemet: Beslutninger fordamper
Se for deg et typisk scenario. En utvikler committer:
feat(canonical): add DuckDB runtime for pipeline stages
Denne commiten representerer et betydelig arkitekturvalg. Teamet vurderte alternativer, veide avveininger, og landet på DuckDB av spesifikke grunner. Men all den konteksten lever i:
- En Slack-tråd (sannsynligvis slettet)
- Noens hukommelse (definitivt falmende)
- En kommentar i koden (kanskje, hvis du er heldig)
Tre måneder senere spør et nytt teammedlem: «Bør jeg bruke DuckDB eller SQLite for dette nye stadiet?» Uten institusjonell hukommelse finner de enten opp hjulet på nytt eller tar inkonsistente valg.
Løkken: Fra commits til kontekst
Mining-arbeidsflyten vår omdanner git-historikk til søkbar kunnskap:
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) │
└───────────────┘
Kjerneinnsikten: både endringslogger og arkitekturbeslutninger flyter fra den samme git-historikken, prosessert gjennom en samlet pipeline. Dette sikrer at ingenting faller mellom to stoler.
Hvordan mining fungerer
Steg 1: Synkroniser indeksen
uv run orkestra mine sync
Denne kommandoen skanner git-historikken og bygger en indeks over alle commits. Den ekstraherer strukturerte signaler fra hver commit:
- Konvensjonell commit-type (
feat,fix,chore,docs) - Scope (hvilken pakke eller område)
- Markører for brytende endringer
- Berørte filer og kompleksitetsmetrikker
Steg 2: Sjekk dekningsstatus
uv run orkestra mine status
Slik ser vår nåværende status ut:
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 prosessert. 476 ble arkitekturbeslutninger. 6 799 ble endringslogg-oppføringer. Hver eneste commit klassifisert.
Steg 3: Hent kandidater for gjennomgang
uv run orkestra mine candidates --limit 50 --full
Dette henter frem commits som ennå ikke er behandlet, med full kontekst for klassifisering:
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}
}
Signalene hjelper til å veilede klassifiseringen: is_releasable_type: true antyder at denne bør vises i endringsloggen. Det store antallet innsettinger og infrastrukturfilene antyder at den også kan være en arkitekturbeslutning.
Steg 4: Klassifiser commits
To stier deler seg her: endringslogg-oppføringer og arkitekturbeslutninger.
For endringslogg-oppføringer:
uv run orkestra mine classify abc123 --changelog added
Dette registrerer at commit abc123 bør vises i endringsloggen under kategorien «Added».
For arkitekturbeslutninger:
Først, hent en reell beslutnings-ID:
uv run orkestra decisions new --domain pipeline --dry-run
# Returns: DEC-PL-143
Klassifiser deretter med beslutnings-ID-en:
uv run orkestra mine classify abc123 --decision DEC-PL-143
Dette knytter commiten til en beslutningsjournal som vil bli opprettet eller oppdatert.
For batch-prosessering (det vi faktisk gjør):
# Generate classifications file with LLM assistance
uv run orkestra mine commit --input classifications.jsonl
JSONL-formatet støtter begge domenene 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"}
Steg 5: Rendre resultater
uv run orkestra changelog render --package <pkg>
Dette genererer per-pakke CHANGELOG.md-filer fra journalen (ledger). Endringsloggene er avledede artefakter — slett dem, og de genereres perfekt på nytt fra kildejournalen.
Strukturen på en beslutningsjournal
Ekstraherte beslutninger blir YAML-filer med rik 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 lenker tilbake til kildecommitene sine. Hver beslutning spesifiserer hvilke filer den påvirker. Sammenhenger mellom beslutninger er eksplisitte.
CLI-integrasjon: Spørring mot institusjonell hukommelse
Dette er der løkken lukkes. Agenter kan spørre mot beslutninger gjennom CLI-et:
# Search by topic
uv run orkestra decisions search --query "retry"
Returnerer beslutninger om retry-logikk, feilhåndtering, gjenopprettingsmønstre.
# Get full details on a specific decision
uv run orkestra decisions info DEC-PL-142
Returnerer hele beslutningsjournalen med kontekst, begrunnelse og konsekvens.
# List recent decisions for context
uv run orkestra decisions list --limit 15
Viser hvilke arkitekturvalg som ble tatt nylig.
Hvordan agenter bruker dette
Orkestratorens grunnleggende instruksjoner inkluderer:
**Essential CLI commands:**
- `orkestra decisions search "X"` — Find architectural decisions
Når en agent blir bedt om å implementere noe relatert til DuckDB, kan den først sjekke:
uv run orkestra decisions search --query "DuckDB"
Og oppdage DEC-PL-142, og lære:
- Hvorfor vi valgte DuckDB (context)
- Hvordan bruke det riktig (agent_guidance)
- Hvilke filer man skal se på (files)
- Hvilke relaterte beslutninger som finnes (related)
Agenten finner ikke opp hjulet på nytt. Den bygger på etablerte mønstre.
Tre-spørsmåls-testen
Ikke hver commit fortjener en beslutningsjournal. Vi bruker Tre-spørsmåls-testen for å filtrere:
- Var dette vanskelig å ta stilling til? Krevde det betydelig analyse, avveining, eller diskusjon?
- Er det kostbart å endre? Ville det å reversere denne beslutningen krevd betydelig omarbeiding?
- Har det systemomfattende konsekvenser? Påvirker det flere pakker eller etablerer det mønstre andre vil følge?
Hvis en commit svarer «ja» på minst ett av disse spørsmålene, er den en kandidat for beslutningsekstraksjon. Vår typiske rate: 1–4 beslutninger per 100 commits (rundt 1–4 %).
For endringslogg-oppføringer er terskelen lavere: enhver brukerrettet endring (funksjoner, feilrettinger, forbedringer) blir registrert. Interne gjøremål, dokumentasjonsoppdateringer og refaktoreringer hoppes typisk over. Vår typiske rate: 30–50 endringslogg-oppføringer per 100 commits.
Datalagring: Append-only journaler
Mining-systemet bruker append-only JSONL-journaler for 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 betyr at flere agenter kan klassifisere commits samtidig uten sammenslåingskonflikter. Hver linje er uavhengig.
Valideringsporter
Før hver mining-økt kjører vi validering:
uv run orkestra mine validate --quick
Dette sjekker:
- Gyldighet av SHA-format
- Samsvar med beslutnings-ID-format
- Ingen duplikate oppføringer for samme SHA
- At refererte beslutninger faktisk finnes
Etter klassifisering validerer vi på nytt før vi committer endringene.
Hvorfor dette betyr noe
Tilbakemeldingsløkken vi har bygget, løser flere problemer:
For nye teammedlemmer: I stedet for å spørre «hvorfor gjorde vi X?», kan de søke i beslutningsregisteret. Konteksten er bevart.
For AI-agenter: De opererer ikke i et vakuum. De kan spørre mot institusjonell kunnskap før de kommer med anbefalinger. Når de blir bedt om å legge til et nytt pipeline-stadium, kan de oppdage DuckDB-mønsteret og følge det.
For arkitektonisk konsistens: Beslutninger er eksplisitte og søkbare. Når noen foreslår en tilnærming som motsier en eksisterende beslutning, kan systemet synliggjøre konflikten.
For endringsloggenerering: Release notes er ikke et hastverksarbeid i siste liten. De er et biprodukt av kontinuerlig klassifisering underveis i utviklingen.
For onboarding: Nye agenter arver hele konteksten til kodebasen. De ser ikke bare koden — de ser beslutningene som formet den.
Nåværende status
Per i dag:
- 15 637 commits prosessert gjennom pipelinen
- 476 arkitekturbeslutninger ekstrahert og dokumentert
- 6 799 endringslogg-oppføringer registrert
- 100 % dekning på tvers av begge domener
Hver commit siden vi startet, er klassifisert. Den institusjonelle hukommelsen er komplett og søkbar.
Kom i gang
Hvis du vil implementere noe lignende:
-
Start med konvensjonelle commits. Mining-pipelinen fungerer best når commits har strukturerte prefikser (
feat:,fix:,chore:). -
Definer domenene dine. Vi bruker domener som
pipeline,agent-design,observability,data-modeling. Disse organiserer beslutninger etter område. -
Bygg klassifiseringsvanen. Mining fungerer når team klassifiserer commits regelmessig. Batch-prosessering med LLM-assistanse hjelper med å skalere.
-
Gjør beslutninger søkbare. Verdien øker når agenter kan søke i beslutninger via CLI. Strukturer resultatet for maskinkonsum.
-
Lukk løkken. Beslutninger bør påvirke fremtidig arbeid. Inkluder beslutningsreferanser i agentinstruksjoner og sjekklister for kodegjennomgang.
Målet er ikke perfekt dokumentasjon. Det er å gjøre hvorfor-et bak endringene tilgjengelig for både mennesker og AI, i dag og seks måneder frem i tid. Når endringer blir institusjonell hukommelse, bygger team videre på etablerte mønstre i stedet for å finne dem opp på nytt.
Mining-arbeidsflyten er en del av orkestreringsmotoren vår, nærmere bestemt context engine-modulen i orkestreringspakken vår.
Relatert lesning
Mer fra Maguyva-byggeloggen
Hvorfor vi oppgraderte kodesøk til voyage-4-large_
Vi flyttet kode-embeddingene våre til voyage-4-large — for tiden på topp på den offentlige RTEB-rangeringen for kode-retrieval. Den ærlige versjonen: kompromisset vi tar, hva vi faktisk indekserer, og hvorfor vi betaler for premium embeddings.
Rekursiv språkforbedring: Kverning av kodeintelligens på tvers av ~280 språk_
Vi støtter kodeintelligens for ~280 språk. Ingen mennesker kan manuelt revidere det. Så vi bygde en rekursiv selvforbedringsløkke for språk — stikkprøver, LLM som dommer, fiks én ting, valider på nytt — og kjører den med en flåte av isolerte agenter helt til ekstraheringen faktisk er riktig, ikke bare grønn.
Multimodalt fusjonssøk: Velge riktig retriever for hvert søk_
Et søk som «hvor er parseConfig definert» krever et annet søk enn «hvordan fungerer autentisering». Maguyva klassifiserer intensjonen, vekter fire retrieval-modaliteter deretter, og fusjonerer resultatene med vektet Reciprocal Rank Fusion.