Siirry sisältöön
cd /blog

Louhinnan työnkulku: miten muutoksista tulee institutionaalista muistia

[Arkkitehtuuri][Työnkulut]

> Git-commiteista tulee jäsenneltyjä muutoslokimerkintöjä ja arkkitehtonisia päätöstietueita, jotka syötetään sitten takaisin tekoälyagenteille kyseltävänä institutionaalisena muistina.

Tämän postauksen luvut heijastavat järjestelmää julkaisuhetkellä (helmikuu 2026). Katso tiimisivumme ajantasaiset luvut.

Jokainen insinööritiimi kohtaa saman haasteen: muutoksia tapahtuu jatkuvasti, mutta niiden takana oleva miksi katoaa. Kuusi kuukautta myöhemmin joku kysyy “miksi otimme DuckDB:n käyttöön putken vaiheissa?”, ja vastaus elää vain sen henkilön päässä, joka teki tuon päätöksen — jos hän on yhä paikalla.

Rakensimme louhintatyönkulun, joka sulkee tämän silmukan. Muutokset virtaavat git-commitien läpi, käsitellään louhintaputkessamme, muuttuvat jäsenneltyiksi muutoslokimerkinnöiksi ja arkkitehtonisiksi päätöstietueiksi, ja syötetään sitten takaisin tekoälyagenteillemme CLI-kyselyjen kautta. Tulos: institutionaalinen muisti, johon sekä ihmiset että tekoäly pääsevät käsiksi.

Ongelma: päätökset haihtuvat

Harkitse tyypillistä skenaariota. Kehittäjä committaa:

feat(canonical): add DuckDB runtime for pipeline stages

Tämä commit edustaa merkittävää arkkitehtonista valintaa. Tiimi arvioi vaihtoehtoja, punnitsi kompromisseja ja päätyi DuckDB:hen tietyistä syistä. Mutta kaikki tuo konteksti elää:

  • Slack-ketjussa (todennäköisesti poistettu)
  • jonkun muistissa (varmasti haalistumassa)
  • kommentissa koodissa (ehkä, jos olet onnekas)

Kolme kuukautta myöhemmin uusi tiimin jäsen kysyy: “Pitäisikö minun käyttää DuckDB:tä vai SQLitea tähän uuteen vaiheeseen?” Ilman institutionaalista muistia he joko keksivät pyörän uudelleen tai tekevät epäjohdonmukaisia valintoja.

Silmukka: commiteista kontekstiin

Louhintatyönkulkumme muuntaa git-historian kyselykelpoiseksi tiedoksi:

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

Avainoivallus: sekä muutoslokit että arkkitehtoniset päätökset virtaavat samasta git-historiasta, käsiteltynä yhtenäisen putken läpi. Tämä varmistaa, ettei mikään putoa rakojen läpi.

Miten louhinta toimii

Vaihe 1: indeksin synkronointi

uv run orkestra mine sync

Tämä komento skannaa git-historian ja rakentaa indeksin kaikista commiteista. Se poimii jäsenneltyjä signaaleja jokaisesta commitista:

  • Konventionaalinen commit-tyyppi (feat, fix, chore, docs)
  • Laajuus (mikä paketti tai alue)
  • Rikkovan muutoksen merkit
  • Kosketetut tiedostot ja monimutkaisuusmetriikat

Vaihe 2: kattavuustilan tarkistus

uv run orkestra mine status

Näin nykyinen tilamme näyttää:

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 commitia käsitelty. 476:sta tuli arkkitehtonisia päätöksiä. 6 799:stä tuli muutoslokimerkintöjä. Jokainen commit luokiteltu.

Vaihe 3: ehdokkaiden hankinta katselmointia varten

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

Tämä nostaa esiin commiteja, joita ei vielä ole käsitelty, täydellä kontekstilla luokittelua varten:

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

Signaalit auttavat ohjaamaan luokittelua: is_releasable_type: true viittaa siihen, että tämän pitäisi näkyä muutoslokissa. Suuri lisäysmäärä ja infrastruktuuritiedostot viittaavat siihen, että se saattaa myös olla arkkitehtoninen päätös.

Vaihe 4: commitien luokittelu

Tässä kohtaa polut haarautuvat kahtia: muutoslokimerkinnät ja arkkitehtoniset päätökset.

Muutoslokimerkinnöille:

uv run orkestra mine classify abc123 --changelog added

Tämä kirjaa, että commitin abc123 pitäisi näkyä muutoslokissa “Added”-kategoriassa.

Arkkitehtonisille päätöksille:

Ensin hanki todellinen päätös-ID:

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

Sitten luokittele päätös-ID:llä:

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

Tämä linkittää commitin päätöstietueeseen, joka luodaan tai päivitetään.

Eräkäsittelylle (mitä oikeasti teemme):

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

JSONL-muoto tukee molempia toimialueita yhdellä läpikäynnillä:

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

Vaihe 5: tulosteiden renderöinti

uv run orkestra changelog render --package <pkg>

Tämä generoi pakettikohtaiset CHANGELOG.md-tiedostot pääkirjasta. Muutoslokit ovat johdettuja artefakteja — poista ne, ja ne generoituvat täydellisesti uudelleen lähdepääkirjasta.

Päätöstietueen rakenne

Poimitut päätökset muuttuvat YAML-tiedostoiksi, joissa on runsaasti metadataa:

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

Jokainen päätös linkittää takaisin lähdecommiteihinsa. Jokainen päätös määrittelee, mihin tiedostoihin se vaikuttaa. Päätösten väliset suhteet ovat eksplisiittisiä.

CLI-integraatio: institutionaalisen muistin kysely

Tässä kohtaa silmukka sulkeutuu. Agentit voivat kysellä päätöksiä CLI:n kautta:

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

Palauttaa päätöksiä uudelleenyrityslogiikasta, virheenkäsittelystä, palautumismalleista.

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

Palauttaa täydellisen päätöstietueen kontekstilla, perusteluilla ja vaikutuksella.

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

Näyttää, mitä arkkitehtonisia valintoja tehtiin äskettäin.

Miten agentit käyttävät tätä

Orkestraattorimme perusohjeisiin kuuluu:

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

Kun agenttia pyydetään toteuttamaan jotain DuckDB:hen liittyvää, se voi ensin tarkistaa:

uv run orkestra decisions search --query "DuckDB"

Ja löytää DEC-PL-142:n, oppien:

  • Miksi valitsimme DuckDB:n (konteksti)
  • Miten sitä käytetään oikein (agent_guidance)
  • Mihin tiedostoihin katsoa (files)
  • Mitä liittyviä päätöksiä on olemassa (related)

Agentti ei keksi pyörää uudelleen. Se rakentaa vakiintuneiden mallien päälle.

Kolmen kysymyksen testi

Ei jokainen commit ansaitse päätöstietuetta. Käytämme Kolmen kysymyksen testiä suodattamiseen:

  1. Oliko tämä vaikea tehdä? Vaatiko se merkittävää analyysiä, kompromissien arviointia tai keskustelua?
  2. Onko sen muuttaminen kallista? Vaatisiko tämän kumoaminen merkittävää uudelleentyötä?
  3. Onko sillä järjestelmänlaajuinen vaikutus? Vaikuttaako se useisiin paketteihin tai luoko se malleja, joita muut seuraavat?

Jos commit vastaa “kyllä” ainakin yhteen näistä kysymyksistä, se on ehdokas päätöspoiminnalle. Tyypillinen suhteemme: 1–4 päätöstä sataa commitia kohti (noin 1–4 %).

Muutoslokimerkinnöille kynnys on matalampi: mikä tahansa käyttäjälle näkyvä muutos (ominaisuudet, korjaukset, parannukset) kirjataan. Sisäiset kotityöt, dokumentaatiopäivitykset ja refaktoroinnit yleensä ohitetaan. Tyypillinen suhteemme: 30–50 muutoslokimerkintää sataa commitia kohti.

Datan tallennus: liitä-vain-pääkirjat

Louhintajärjestelmä käyttää liitä-vain-JSONL-pääkirjoja konfliktitonta moniagenttista toimintaa varten:

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-muoto merge=union:lla .gitattributes:ssa tarkoittaa, että useat agentit voivat luokitella commiteja samanaikaisesti ilman yhdistämiskonflikteja. Jokainen rivi on riippumaton.

Validointiportit

Ennen mitä tahansa louhintaistuntoa ajamme validoinnin:

uv run orkestra mine validate --quick

Tämä tarkistaa:

  • SHA-muodon kelvollisuuden
  • Päätös-ID-muodon vaatimustenmukaisuuden
  • Ei duplikaattimerkintöjä samalle SHA:lle
  • Että viitatut päätökset todella ovat olemassa

Luokittelun jälkeen validoimme uudelleen ennen muutosten committaamista.

Miksi tämä merkitsee

Rakentamamme palautesilmukka ratkaisee useita ongelmia:

Uusille tiimin jäsenille: sen sijaan että kysyisivät “miksi teimme X:n?”, he voivat hakea päätösrekisteristä. Konteksti on säilytetty.

Tekoälyagenteille: ne eivät toimi tyhjiössä. Ne voivat kysellä institutionaalista tietoa ennen suositusten antamista. Kun niitä pyydetään lisäämään uusi putkivaihe, ne voivat löytää DuckDB-mallin ja seurata sitä.

Arkkitehtoniselle johdonmukaisuudelle: päätökset ovat eksplisiittisiä ja haettavissa. Kun joku ehdottaa lähestymistapaa, joka on ristiriidassa olemassa olevan päätöksen kanssa, järjestelmä voi nostaa ristiriidan esiin.

Muutoslokien generoinnille: julkaisumuistiinpanot eivät ole viime hetken kiireenkiirettä. Ne ovat sivutuote jatkuvasta luokittelusta kehityksen aikana.

Perehdytykselle: uudet agentit perivät koodikannan täyden kontekstin. Ne eivät vain näe koodia — ne näkevät päätökset, jotka muokkasivat sitä.

Nykytila

Tänään:

  • 15 637 commitia käsitelty putken läpi
  • 476 arkkitehtonista päätöstä poimittu ja dokumentoitu
  • 6 799 muutoslokimerkintää kirjattu
  • 100 %:n kattavuus molemmilla toimialueilla

Jokainen commit siitä lähtien, kun aloitimme, on luokiteltu. Institutionaalinen muisti on täydellinen ja kyselykelpoinen.

Aloittaminen

Jos haluat toteuttaa jotain vastaavaa:

  1. Aloita konventionaalisilla commiteilla. Louhintaputki toimii parhaiten, kun commiteilla on jäsennellyt etuliitteet (feat:, fix:, chore:).

  2. Määrittele toimialueesi. Käytämme toimialueita kuten pipeline, agent-design, observability, data-modeling. Nämä järjestävät päätökset alueen mukaan.

  3. Rakenna luokittelutottumus. Louhinta toimii, kun tiimit luokittelevat commiteja säännöllisesti. Eräkäsittely LLM-avustuksella auttaa skaalautumaan.

  4. Tee päätöksistä kyselykelpoisia. Arvo kasvaa, kun agentit voivat hakea päätöksiä CLI:n kautta. Rakenna tulosteesi koneluettavaksi.

  5. Sulje silmukka. Päätösten pitäisi vaikuttaa tulevaan työhön. Sisällytä päätösviittauksia agenttiohjeisiin ja koodikatselmuslistoihin.

Tavoite ei ole täydellinen dokumentaatio. Se on tehdä muutosten takana oleva miksi saavutettavaksi sekä ihmisille että tekoälylle, tänään ja kuuden kuukauden kuluttua. Kun muutoksista tulee institutionaalista muistia, tiimit rakentavat vakiintuneiden mallien päälle sen sijaan että keksisivät ne uudelleen.


Louhintatyönkulku on osa orkestrointimoottoriamme, erityisesti orkestrointipakettimme kontekstimoottorimoduulia.

Aiheeseen liittyvää

Lisää Maguyva-projektin rakennuslokista