Hopp til innhold
cd /blog

Mining av løkken: Hvordan endringer blir institusjonell hukommelse

[Arkitektur][Arbeidsflyter]

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

  1. Var dette vanskelig å ta stilling til? Krevde det betydelig analyse, avveining, eller diskusjon?
  2. Er det kostbart å endre? Ville det å reversere denne beslutningen krevd betydelig omarbeiding?
  3. 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:

  1. Start med konvensjonelle commits. Mining-pipelinen fungerer best når commits har strukturerte prefikser (feat:, fix:, chore:).

  2. Definer domenene dine. Vi bruker domener som pipeline, agent-design, observability, data-modeling. Disse organiserer beslutninger etter område.

  3. Bygg klassifiseringsvanen. Mining fungerer når team klassifiserer commits regelmessig. Batch-prosessering med LLM-assistanse hjelper med å skalere.

  4. Gjør beslutninger søkbare. Verdien øker når agenter kan søke i beslutninger via CLI. Strukturer resultatet for maskinkonsum.

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