Hoppa till innehåll
cd /blog

Att utvinna loopen: hur ändringar blir institutionellt minne

[Arkitektur][Arbetsflöden]

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

  1. Var det svårt att fatta? Krävde det betydande analys, avvägningsutvärdering eller diskussion?
  2. Är det kostsamt att ändra? Skulle det kräva betydande omarbete att göra beslutet ogjort?
  3. 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:

  1. Börja med conventional commits. Mining-pipelinen fungerar bäst när commits har strukturerade prefix (feat:, fix:, chore:).

  2. Definiera dina domäner. Vi använder domäner som pipeline, agent-design, observability, data-modeling. De organiserar beslut efter område.

  3. Bygg upp klassificeringsvanan. Mining fungerar när team regelbundet klassificerar commits. Batchbearbetning med LLM-hjälp gör det skalbart.

  4. 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.

  5. 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