Tidligere version (v3) (2026-06-10, "Calque-pass + serie-konsistens")
Dette er en arkiveret tidligere udgave af denne post. Den aktuelle version kan være ændret. Læs den aktuelle version →
Opus-review (score 60, Terminology 2/5): 'stagede filer' → 'staged filer', 'skanner' → 'scanner', 'Strøm én pass' → 'én streaming-pass', 'Du skar ind' → 'Jeg stoppede op og skrev', genusfejl ('det output', 'det samme staged-set'). 'Fire knuder' → 'fire nodes' så terminologien matcher indlæg 3. Cliffhanger-slutningen kortet ned til seriens punchline.
Fra ændrede filer til commit messages
Pks brain commit-plan kører grafens reverse query: tag staged filer, find de prompts der drev hver ændring, returnér grupperet plan. Det 4. og sidste indlæg i serien viser hvordan det blev til en /commit-message-skill — og hvorfor den var ubrugelig før vi flyttede planneren fra rå-JSONL-scanner til firehose-direct-read.
52 staged filer. 200 sekunder. Tre minutter på at vente på en commit message — det er længe nok til at jeg åbner en anden fane og glemmer hvad jeg var i gang med. Da pks brain commit-plan begyndte at læse grafen direkte i stedet for at re-parse rå JSONL hver gang, faldt de 200 sekunder til 1,3. Speedup på ~165×. Det forvandlede /commit-message-skillet fra "for langsom til at bruge" til "kør den hver gang".
Det her er det 4. og sidste indlæg i serien om pks brain (efter hvorfor AI-hjernen eksisterer, hvad den producerer og hvordan grafen er bygget op). Det handler om at lukke loopen: tage grafen fra indlæg 3, køre dens reverse query mod staged filer, og bruge resultatet til at skrive en commit message der ved hvorfor — ikke kun hvad.
Sessionen startede med at jeg ledte efter en gammel samtale jeg havde glemt indholdet af:
AI-hjernen fandt den. Tre dage gammel session, fuld af notater om hvordan man linker filer til de sessioner og prompts der havde rørt dem. Spørgsmålet kom umiddelbart:
Hvad skillen gør
/commit-message er en Claude Code-skill der kører hver gang man har staged filer og vil skrive en ordentlig commit-message. Flowet er:
git diff --cached --name-only→ den nuværende staged-listepks brain commit-plan --files-from <list> --include-prompts --format json→ grafens reverse querygit diff --cached→ den faktiske diff (hvad-er-ændret)- Syntese: subject = hvad (ét konkret user-visible change), body = hvorfor (syntetiseret fra de prompts der drev ændringerne)
- Output i Conventional Commits-format, så
semantic-releaseog lignende kan rulle dem sammen til release notes senere
Pointen er at AI-hjernen kender konteksten bag hver fil-ændring — ikke kun selve ændringen. Når man skriver feat(blog): publish coolify-destinations-pr post er det fordi grafen kunne pege på de prompts der oprindeligt diskuterede coolify-destinations-PR'en — ikke fordi modellen gættede et subject ud fra filnavnene.
Grafens reverse query
Det 3. indlæg etablerede at grafen er en DAG med fire nodes: Session → Prompt → ToolCall → File. Forward er trivielt. Reverse er det interessante:

pks brain commit-plan kører præcis den reverse query: for hver staged fil finder den ToolCalls i files.jsonl der har skrevet til den filsti; for hver matched ToolCall finder den den seneste brugerprompt i prompts.jsonl med samme sessionId og timestampUtc ≤ tool-call.ts; til sidst grupperer den efter primary-session og returnerer.
Resultatet er en JSON med:
groups[]— filer der hænger sammen (samme primary session)groups[i].prompts[]— de brugerprompts der drev edits til de filer (verbatim tekst, timestamp)groups[i].contributing_sessions[]— andre sessioner der også rørte filerne
Skillet bruger det output til at vælge en type (feat/fix/chore/docs), et scope (det mest specifikke område), og et subject der reflekterer det mest user-visible change — så syntetiserer body'en fra prompt-teksterne uden at citere dem ordret.
Hvad gjorde den ubrugelig først
Da skillet blev skrevet, var pks brain commit-plan implementeret oven på en per-fil scanner der re-parsede rå ~/.claude/projects/**/*.jsonl fra bunden af hver gang. For 52 staged filer tog det ~200 sekunder. Tre minutter. Det er ubrugeligt for et "tryk-her-så-commit"-flow.
Jeg stoppede op og skrev:
Den observation delte arbejdet op i to features (præcis som indlæg 3 beskriver): ingest-laget — som allerede producerede en graf i form af firehoses — og graf-laget, der bare skulle læse den eksisterende graf i stedet for at re-parse rå-data.
Fixet var en ~80-linjers omskrivning af BrainCommitPlanner i pks-cli: én streaming-pass over files.jsonl filtreret til input-filerne, en binary-search-join mod prompts.jsonl for prompts før hver edit-timestamp, scanneren beholdt som fallback når firehose'en mangler, og en auto-ingest før query så grafen er frisk.
Resultatet på det samme 52-filers staged-set:
| Implementering | Tid |
|---|---|
| Firehose grep (rå lookup over indekseret firehose) | ~10 ms |
pks brain commit-plan (ny — auto-ingest + firehose-read) | ~1,3 s |
pks brain commit-plan (gammel — per-fil scanner) | ~200 s |
Speedup: ~165×. Det forvandlede skillet fra "for langsom til at bruge" til "kør den hver gang".
Dogfood-momentet
Den her serie er skrevet i den session hvor skiftet skete. Den her commit blev skrevet af /commit-message selv — skillet brugte den nye firehose-implementering til at finde de prompts der drev sin egen rewrite, gennem en JSON-output på 1,3 sekunder, og syntetiserede:
feat(brain): wire commit-planner to firehose graph
The graph itself already existed — pks brain ingest materialises
files.jsonl as the File↔Session edge table — but BrainCommitPlanner
ignored it and re-parsed every raw ~/.claude/projects/**/*.jsonl per
input file, taking ~3 minutes for a 52-file plan. The planner now reads
the firehose directly with a binary-search join on prompts.jsonl and
keeps the scanner as fallback when the firehose is absent.
Hele kæden — ingest, firehose, graf-query, skill, conventional commit — lukkede loopen på sig selv. Se artifact-siden for /commit-message hvis du vil læse selve skillen.
Hvad jeg konkret får ud af det
Tre ting jeg kan mærke forskel på:
- Bedre commit-messages. Subject = ét user-visible change. Body = hvorfor, ikke hvad. Hvad → diff. Hvorfor → kun synlig hvis nogen har et signal fra prompts der drev edits. Det signal fandtes ikke før grafen.
- Bedre release notes. En release-pipeline (semantic-release / conventional-changelog) tager subject-listen og bygger "## Features" / "## Bug Fixes" automatisk. Body'erne overlever som expandable detail. Pludselig er release notes ikke et review-step men en bivirkning.
- Sporbarhed. Hvert commit kan slås tilbage til præcis de prompts der diskuterede det. Det er ikke et "AI wrote this" disclaimer — det er at kunne læse hvad der blev sagt før koden blev til.
Slut på serien
Det her var det 4. og sidste indlæg i serien om pks brain. Genopfrisk de tre andre hvis du sprang ind midtvejs:
- Hjernen bag — hvorfor AI-hjernen overhovedet eksisterer
- En wiki skrevet af vores AI-hjerne — hvad den producerer
- Grafen var der hele tiden — hvordan den er bygget op
Måske kommer der et 5. indlæg en dag med en interaktiv visualisering af grafen. Måske ikke. Serien lukker her: fire indlæg, ét repo, ~7.000 prompts kondenseret til en DAG der ved hvorfor mine filer eksisterer.