Att utvinna loopen: hur ändringar blir institutionellt minne
> Git-commits blir strukturerade changelog-poster och arkitektoniska beslutsregister, som sedan matas tillbaka till AI-agenter som sökbart institutionellt minne.
Siffrorna i det här inlägget speglar systemet vid publicering (februari 2026). Se vår teamsida för aktuella siffror.
Varje utvecklingsteam möter samma utmaning: ändringar sker hela tiden, men varför bakom dessa ändringar försvinner. Sex månader senare frågar någon “varför valde vi DuckDB för pipeline-steg?” och svaret finns bara i huvudet på den som fattade det beslutet — om personen fortfarande är kvar.
Vi byggde ett mining-arbetsflöde som sluter den här loopen. Ändringar flödar genom git-commits, bearbetas av vår mining-pipeline, blir strukturerade changelog-poster och arkitektoniska beslutsregister, och matas sedan tillbaka till våra AI-agenter via CLI-frågor. Resultatet: institutionellt minne som både människor och AI kan komma åt.
Problemet: beslut avdunstar
Betrakta ett typiskt scenario. En utvecklare committar:
feat(canonical): add DuckDB runtime for pipeline stages
Den här commiten representerar ett betydande arkitektoniskt val. Teamet utvärderade alternativ, övervägde avvägningar, och landade i DuckDB av specifika skäl. Men all den kontexten finns bara i:
- En Slack-tråd (förmodligen raderad)
- Någons minne (garanterat bleknande)
- En kommentar i koden (kanske, om du har tur)
Tre månader senare frågar en ny teammedlem: “Ska jag använda DuckDB eller SQLite för det här nya steget?” Utan institutionellt minne uppfinner de antingen hjulet på nytt eller fattar inkonsekventa beslut.
Loopen: från commits till kontext
Vårt mining-arbetsflöde omvandlar git-historik till sökbar kunskap:
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 centrala insikten: både changelogs och arkitektoniska beslut flödar från samma git-historik, bearbetade genom en enhetlig pipeline. Det säkerställer att ingenting faller mellan stolarna.
Så fungerar mining
Steg 1: Synka indexet
uv run orkestra mine sync
Det här kommandot skannar git-historiken och bygger ett index över alla commits. Det extraherar strukturerade signaler från varje commit:
- Conventional commit-typ (
feat,fix,chore,docs) - Scope (vilket paket eller område)
- Markörer för brytande ändringar
- Berörda filer och komplexitetsmått
Steg 2: Kontrollera täckningsstatus
uv run orkestra mine status
Så här ser vår nuvarande 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 bearbetade. 476 blev arkitektoniska beslut. 6 799 blev changelog-poster. Varje commit klassificerad.
Steg 3: Hämta kandidater för granskning
uv run orkestra mine candidates --limit 50 --full
Det här lyfter fram commits som ännu inte bearbetats, med full kontext för 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}
}
Signalerna hjälper till att styra klassificeringen: is_releasable_type: true antyder att det här bör synas i changelogen. Det stora antalet insättningar och infrastrukturfilerna antyder att det också kan vara ett arkitektoniskt beslut.
Steg 4: Klassificera commits
Här delar sig två vägar: changelog-poster och arkitektoniska beslut.
För changelog-poster:
uv run orkestra mine classify abc123 --changelog added
Det här registrerar att commit abc123 bör synas i changelogen under kategorin “Added”.
För arkitektoniska beslut:
Skaffa först ett riktigt beslut-ID:
uv run orkestra decisions new --domain pipeline --dry-run
# Returns: DEC-PL-143
Klassificera sedan med beslut-ID:t:
uv run orkestra mine classify abc123 --decision DEC-PL-143
Det här länkar commiten till ett beslutsregister som kommer att skapas eller uppdateras.
För batchbearbetning (vad vi faktiskt gör):
# Generate classifications file with LLM assistance
uv run orkestra mine commit --input classifications.jsonl
JSONL-formatet stödjer båda domänerna i en enda genomgång:
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: Rendera utdata
uv run orkestra changelog render --package <pkg>
Det här genererar CHANGELOG.md-filer per paket från liggaren. Changelogsen är härledda artefakter — radera dem och de återskapas perfekt från källiggaren.
Beslutsregistrets struktur
Extraherade beslut 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
Varje beslut länkar tillbaka till sina källcommits. Varje beslut anger vilka filer det påverkar. Relationer mellan beslut är explicita.
CLI-integration: att fråga institutionellt minne
Det är här loopen sluts. Agenter kan fråga beslut via CLI:t:
# Search by topic
uv run orkestra decisions search --query "retry"
Returnerar beslut om återförsökslogik, felhantering, återhämtningsmönster.
# Get full details on a specific decision
uv run orkestra decisions info DEC-PL-142
Returnerar det fullständiga beslutsregistret med kontext, motivering och effekt.
# List recent decisions for context
uv run orkestra decisions list --limit 15
Visar vilka arkitektoniska val som gjorts nyligen.
Hur agenter använder det här
Vår orkestrerares grundinstruktioner inkluderar:
**Essential CLI commands:**
- `orkestra decisions search "X"` — Find architectural decisions
När en agent ombeds implementera något relaterat till DuckDB kan den först kontrollera:
uv run orkestra decisions search --query "DuckDB"
Och upptäcka DEC-PL-142, och lära sig:
- Varför vi valde DuckDB (context)
- Hur man använder det korrekt (agent_guidance)
- Vilka filer man ska titta på (files)
- Vilka relaterade beslut som finns (related)
Agenten uppfinner inte hjulet på nytt. Den bygger vidare på etablerade mönster.
Trefrågorstestet
Inte varje commit förtjänar ett beslutsregister. Vi använder Trefrågorstestet för att filtrera:
- Var det svårt att fatta? Krävde det betydande analys, avvägningsutvärdering eller diskussion?
- Är det kostsamt att ändra? Skulle det kräva betydande omarbete att göra beslutet ogjort?
- Har det systemomfattande påverkan? Påverkar det flera paket eller etablerar det mönster andra kommer att följa?
Om en commit svarar “ja” på minst en av dessa frågor är den en kandidat för beslutsextraktion. Vår typiska andel: 1–4 beslut per 100 commits (cirka 1–4 %).
För changelog-poster är ribban lägre: varje användarvänd ändring (funktioner, fixar, förbättringar) registreras. Interna sysslor, dokumentationsuppdateringar och refaktoreringar hoppas vanligtvis över. Vår typiska andel: 30–50 changelog-poster per 100 commits.
Datalagring: append-only-liggare
Mining-systemet använder append-only JSONL-liggare för konfliktfri drift med flera agenter:
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 innebär att flera agenter kan klassificera commits samtidigt utan sammanslagningskonflikter. Varje rad är oberoende.
Valideringsgrindar
Innan varje mining-session kör vi validering:
uv run orkestra mine validate --quick
Det här kontrollerar:
- Giltig SHA-formatering
- Efterlevnad av beslut-ID-format
- Inga dubbletter för samma SHA
- Att refererade beslut faktiskt existerar
Efter klassificering validerar vi igen innan vi committar ändringarna.
Varför det här spelar roll
Återkopplingsloopen vi byggt löser flera problem:
För nya teammedlemmar: Istället för att fråga “varför gjorde vi X?” kan de söka i beslutsregistret. Kontexten är bevarad.
För AI-agenter: De verkar inte i ett vakuum. De kan fråga institutionell kunskap innan de ger rekommendationer. När de ombeds lägga till ett nytt pipeline-steg kan de upptäcka DuckDB-mönstret och följa det.
För arkitektonisk konsekvens: Beslut är explicita och sökbara. När någon föreslår en metod som strider mot ett befintligt beslut kan systemet lyfta fram konflikten.
För changelog-generering: Versionsanteckningar är inte en sista-minuten-stress. De är en biprodukt av kontinuerlig klassificering under utveckling.
För onboarding: Nya agenter ärver kodbasens fulla kontext. De ser inte bara koden — de ser besluten som formade den.
Nuvarande läge
Per idag:
- 15 637 commits bearbetade genom pipelinen
- 476 arkitektoniska beslut extraherade och dokumenterade
- 6 799 changelog-poster registrerade
- 100 % täckning över båda domänerna
Varje commit sedan vi började har klassificerats. Det institutionella minnet är komplett och sökbart.
Komma igång
Om du vill implementera något liknande:
-
Börja med conventional commits. Mining-pipelinen fungerar bäst när commits har strukturerade prefix (
feat:,fix:,chore:). -
Definiera dina domäner. Vi använder domäner som
pipeline,agent-design,observability,data-modeling. De organiserar beslut efter område. -
Bygg upp klassificeringsvanan. Mining fungerar när team regelbundet klassificerar commits. Batchbearbetning med LLM-hjälp gör det skalbart.
-
Gör besluten sökbara. Värdet växer när agenter kan söka beslut via CLI:t. Strukturera din utdata för maskinkonsumtion.
-
Slut loopen. Beslut bör påverka framtida arbete. Inkludera beslutsreferenser i agentinstruktioner och checklistor för kodgranskning.
Målet är inte perfekt dokumentation. Det är att göra varför bakom ändringar tillgängligt för både människor och AI, idag och om sex månader. När ändringar blir institutionellt minne bygger team vidare på etablerade mönster istället för att uppfinna dem på nytt.
Mining-arbetsflödet är en del av vår orkestreringsmotor, närmare bestämt kontextmotor-modulen i vårt orkestreringspaket.
Relaterad läsning
Mer från byggloggen för Maguyva
Varför vi uppgraderade kodsökningen till voyage-4-large_
Vi flyttade våra kodinbäddningar till voyage-4-large — för närvarande etta på den offentliga RTEB-topplistan för kodhämtning. Den ärliga versionen: avvägningen vi gör, vad vi faktiskt indexerar, och varför vi betalar för premiuminbäddningar.
Rekursiv självförbättring för språk: att slita fram kodintelligens över ~280 språk_
Vi stöder kodintelligens för cirka 280 språk. Ingen människa kan granska det för hand. Så vi byggde en rekursiv självförbättringsloop för språk — stickprov, LLM som domare, fixa en sak, omvalidera — och kör den med en flotta av isolerade agenter tills extraktionen faktiskt är korrekt, inte bara grön.
Multimodal fusionssökning: att välja rätt hämtare för varje sökfråga_
En sökfråga som 'var är parseConfig definierad' vill ha en annan typ av sökning än 'hur fungerar auth'. Maguyva klassificerar avsikten, viktar fyra hämtningslägen därefter, och slår samman resultaten med viktad Reciprocal Rank Fusion.