Spring til indhold
DApks-brainagentic-tooling

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.

Scoret for

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:

min prompt
1 lines2026-05-27 08:10
we had a session a few days ago about writing something for pks brain to be able to query which sessions had touched a file, can you find it

Found it.

Session: 18377515-f8c8-4f45-a0d5-efb302e4c222.jsonl — May 24, ~20:13 UTC.

What it was about: A graph-based design for pks brain that tracks which Claude Code sessions edited which files, so you can group uncommitted files into smart commits. Four-node graph: sessions (jsonl) → prompts → tool calls → files. Captured live via a Stop hook into .pks/brain/ (SQLite/JSONL), exposed as something like pks brain commit-plan to answer "which sessions touched these dirty files" and generate commit messages from session context. You also asked to review the product-cli graphs framework before dismissing it.

Starting quote from you: "my problem is more the other way around — I end up with a lot of uncommitted files and would like a smart way to find out how to group them based on AI sessions and generate good commit messages."

Want me to open the transcript or extract the design notes into a memory entry?

8 værktøjer3K tok2 min

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:

human prompt
1 lines
based on the work in it, can we do a skill that /commit-message that will query based on staged files and generate a good commit message following best practice that will generatre a nice release overview when the release pipelien runs later?

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:

  1. git diff --cached --name-only → den nuværende staged-liste
  2. pks brain commit-plan --files-from <list> --include-prompts --format json → grafens reverse query
  3. git diff --cached → den faktiske diff (hvad-er-ændret)
  4. Syntese: subject = hvad (ét konkret user-visible change), body = hvorfor (syntetiseret fra de prompts der drev ændringerne)
  5. Output i Conventional Commits-format, så semantic-release og 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:

DAG-diagram med fire nodes forbundet med tre edges — den samme DAG som i indlæg 3, brugt her som reference for reverse-queryen

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:

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:

human prompt
1 lines
the pks brain call was slow, was this because it had to scan all files. Can we try build the brain graph and see if the query for the same files then are close to instant?

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:

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

min prompt/commit-message
1 lines2026-05-27 09:23
commit this with /commit-message
Dogfood-momentet, verbatim.
13 værktøjer17K tok
commitbb8755epks-cli

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

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:

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.

Denne post er blevet revideret 4 gange — se hele historikken
  1. Førstegangs ai-draft. Havde to pseudo-terminaler der ikke var rigtige shell-sessioner (benchmark-tabel og commit-hash + body) som tvang horisontal scroll på mobile. Manglede en artifact-side for /commit-message-skillet. Pks writing score 52.

  2. Erstattet benchmark-pseudo-terminalen med en markdown-tabel (alignment-decoration, ikke real terminal-output). Indført ny `<CommitBlock>`-komponent som rendrer commit-hash + body som ét semantisk kort i stedet for to separate kodeblokke. Tilføjet artifact-side for /commit-message-skillet med fil-tree + inline SKILL.md.

  3. Erstattet meta-narrativet ('Jeg startede session med at lede efter en gammel samtale…') med en number-first lede: '52 stagede filer. 200 sekunder. […] faldt til 1,3.' Samme greb der løftede post 1 fra Hook 2 til 4. Humanprompt-blokke bevaret verbatim, blot demoteret til kontekst efter punchline.

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

  5. To sessionstory-blokke fra session c848c842: (1) 'we had a session a few days ago' med grep-jagten og 'Found it'-svaret; (2) 'commit this with /commit-message' med selektiv staging, 1,3s-planen, commit-bekræftelsen og bb8755e — verbatim.