Tidligere version (v2) (2026-05-29, "Naturalness-picks")
Dette er en arkiveret tidligere udgave af denne post. Den aktuelle version kan være ændret. Læs den aktuelle version →
Naturalness-pass (28.-29. maj) der forkortede sætninger ud fra NATURALNESS-PICKS. Passen fjernede undervejs firehose-sektionens lead-ins (prompts.jsonl/tools.jsonl-overskrifterne) og efterlod 'Det er bevidst.' uden antecedent — rettet i v3.
Grafen var der hele tiden
Pks brain ingest producerede ikke en log. Den producerede en graf. Fire nodes, tre edges, og en join-akse jeg ikke kunne se før product-cli viste mig hvordan en typed DAG ser ud andre steder. Det 3. indlæg om hvordan AI-hjernen er bygget op under motorhjelmen.
Da jeg startede pks brain 14. maj havde jeg ikke en graf i hovedet. Jeg havde fire JSONL-filer. Det tog mig et par uger at se at det var det samme.
Det her er det 3. indlæg i serien om pks brain. I det første gennemgik jeg hvorfor AI-hjernen eksisterer. I det andet viste jeg hvad den producerer.
Erkendelsen kom fra dig
Jeg sad i en session og troede stadig vi byggede én ting. Så skrev jeg den her prompt:
Den prompt opdelte det i to: ingest-laget (deterministisk firehose-dump) og graf-laget (det der binder noderne sammen).
Fire nodes, tre edges
DAG'en pks brain producerer består af præcis fire node-typer:
- Session — én Claude Code-session, identificeret ved UUID. Lever som en JSONL-fil i
~/.claude/projects/<projekt>/<uuid>.jsonl. - Prompt — én brugerprompt inde i en session. Tekst, timestamp, eventuel slash-command.
- ToolCall — én tool-invokation drevet af en prompt. Værktøjsnavn, varighed, fejl-flag, parent assistant-uuid.
- File — én fil rørt af en ToolCall. Filsti, op (
read/write/edit/multi-edit), success-flag.
Mellem dem er der tre edges — alle peger samme vej:
Session ──contains──→ PromptPrompt ──drove──→ ToolCallToolCall ──wrote/edited/read──→ File
Visuelt er det den her struktur fra det første indlæg — værd at have foran sig:

Det er en DAG — alle edges peger nedad, ingen cykler. Det er det der gør queries forudsigelige. Jeg risikerer aldrig at en File-lookup løber tilbage til sig selv.
Firehose-rækker er edges forklædt som tabelrækker
Hvis man kun kigger på filerne, ligner de almindelige tabelrækker.
I grafen bliver rækken til to ting: Prompt-noden og Session → Prompt-edgen:
{
"sessionId": "1a475348-b3f7-4038-8256-2f364859c3d2",
"projectSlug": "-workspaces-agentic-live-www--...",
"timestampUtc": "2026-04-06T15:28:44.458Z",
"promptId": "0c2762b1-7e6f-45bd-8372-7b499b8a6edd",
"uuid": "85993c63-296b-4d22-a029-9ddacb9a9db5",
"text": "Project: pks-agent-inbox\nan email inbox for agents\n\nScope: scarfold\n\n...",
"textHash": "d39524e8cbdf3c4c",
"cwd": "/workspaces/agentic-live-www/.agentics/_work/...",
"gitBranch": "task/mnmzxlux-85f5wh",
"length": 1901,
"isSlash": false
}
Rækken bliver til ToolCall-noden og edgen tilbage til Prompt via parentAssistantUuid:
{
"sessionId": "agent-a6e61f715b03161e3",
"projectSlug": "-tmp-pks-runner-jobs-...",
"timestampUtc": "2026-04-12T15:40:17.614Z",
"toolName": "Glob",
"toolUseId": "toolu_014X92w1RkizWovUjbToPuTf",
"inputDigest": "f7361c8f7acae6c4",
"inputPreview": "{\"pattern\":\"/tmp/pks-runner-jobs/.../**/*\"}",
"parentAssistantUuid": "c0c06cbd-5884-4885-85bb-5d27f47348f0",
"durationMs": 16,
"isError": false,
"resultSize": 1217,
"isMcp": false,
"isSubagent": false
}
files.jsonl — én række pr. fil-operation. Repræsenterer både File-noden og wrote/edited/read-edgen fra ToolCall:
{
"sessionId": "agent-a6e61f715b03161e3",
"projectSlug": "-tmp-pks-runner-jobs-...",
"timestampUtc": "2026-04-12T15:45:18.075Z",
"op": "write",
"filePath": "/tmp/pks-runner-jobs/.../design-system/components.md",
"success": true
}
errors.jsonl — her markerer jeg de ToolCalls der fejlede. Fejlen er metadata på ToolCall, ikke en node i sig selv.
Joinet er gratis fordi der er en timestamp
Hvis jeg har en fil og vil finde prompten bag edit'en, er opskriften simpel: filePath først, derefter seneste prompt i samme session før fileTs.
I det 4. indlæg bruger pks brain commit-plan præcis den lookup. Den bygger ikke grafen i memory først.
Deterministisk vs. AI-syntetiseret
Det er bevidst. Hele firehose'en skal kunne genberegnes gratis.
Oven på den deterministiske graf ligger to AI-lag:
extract — modellen laver et markdown-resumé pr. session ud fra prompts.jsonl, tools.jsonl og files.jsonl filtreret til den session. synth + wiki — finder klynger af sessions med samme tema (extract-tekst, filstier, tool-mønstre) og skriver én wiki-side pr. klynge.
Jeg kan ændre extract-laget og genkøre extracts uden at røre ingest.
Hvorfor det er en DAG og ikke "bare" en tabel
Jeg overvejede faktisk at slå alle fire firehoses sammen til én bredtabel: (session_id, prompt_id, tool_call_id, file_path, timestamp). Det ville fungere for de fleste queries.
Som tabel bliver det bare state. Som DAG kan jeg se præcis hvilken prompt der førte til hvilket edit.
Næste indlæg
I det 4. indlæg bruger jeg grafen til noget konkret: staged filer ind, reverse query over grafen, commit-messages ud.