Ich war auf einen Verweis auf Entwicklertagebücher gestoßen: die Art, die Spielestudios wie Paradox veröffentlichen, die Art, die einzelne Entwickler in simplen Textdateien führen, die Art, die gelegentlich als lange Blogbeiträge auftaucht, in denen jemand erklärt, wie er etwas tatsächlich gebaut hat. Ich bat Perplexity um eine kurze Zusammenfassung der Geschichte dieses Formats, und zurück kam eine säuberliche Taxonomie: Tagebücher aus der Spieleentwicklung, persönliche Coding-Logs, moderne Cloud-Varianten, die sich automatisch aus der Versionskontrolle generieren.
Die Cloud-Variante klingt auf den ersten Blick interessant und enttäuscht beim genaueren Hinsehen. Wer Dokumentation automatisch aus Commit-Messages erzeugt, bekommt etwas, das niemand liest, weil das Modell dessen, was passiert ist, falsch ist. Commits sind die Artefakte der Arbeit, nicht ihr Ablauf. Sie sagen Ihnen, dass bucket.py um 14:32 geändert wurde, aber nicht, dass die erste Ringpuffer-Implementierung Kontext verworfen hat, den ich behalten wollte, dass ich vierzig Minuten lang versucht habe, Events nach Token-Anzahl zu gewichten, bevor mir klar wurde, dass die Token-Anzahl kein Signal für Relevanz ist, und dass ich dann auf einen inhaltsbasierten Filter bei der Aufnahme umgeschwenkt bin. Die Textur steckt in diesen vierzig Minuten, und git log hat nichts davon.
Bei KI-gestützter Entwicklung ist das, glaube ich, noch wichtiger als beim Programmieren allein. Wenn ich mich mit Claude Code hinsetze, enthält die Session eine Denkspur: was probiert wurde, die Sackgassen, die Momente, in denen ich den Kurs korrigiere, der Sub-Agent, der mit Timings zurückkam, die nicht zu meinen Annahmen passten. Nichts davon überlebt die Session. Wenn ich das Projekt das nächste Mal öffne oder ein anderer Agent es übernimmt, ist das Gespräch weg. Die Commits bleiben. Die Textur ist verloren.
Also fragte ich Claude, was es bräuchte, um einen Claude-Code-Skill zu bauen, der das festhält: ein echtes Tagebuch, geschrieben in dem Ton, den man am Ende eines Arbeitstags tatsächlich in einem Notizbuch anschlägt, kein automatisch generiertes Changelog.
Was der erste Entwurf falsch machte
Der erste Impuls war Struktur. Jeder Eintrag sollte Abschnitte haben: Kontext, Versuche, Ergebnis, Kurswechsel, Lektionen. Frontmatter mit Tags. Einen Zeitstempelbereich. Etwas, das im Verzeichnislisting ordentlich aussieht und sich leicht greppen lässt.
Das war falsch. Die frühen Skizzen lasen sich wie Berichte, nicht wie Tagebucheinträge. Die Struktur erledigte die Arbeit, die der Prosa zugestanden hätte. Echte Coding-Tagebücher, wie Menschen sie tatsächlich führen, lesen sich eher so:
Angefangen mit dem Shishi-Bucket, einem inhaltsbasierten Event-Akkumulator für tmuxllm. Erster Impuls: ein Ringpuffer mit festem Fenster. Etwa achtzig Zeilen geschrieben und gegen die Wand gefahren: Wenn Events in Schüben kommen, verwirft das Fenster Kontext, den ich behalten will, weil Relevanz nicht mit Aktualität korreliert. Als Nächstes versucht, nach Token-Anzahl zu gewichten: das Schwere behalten, den Rest verwerfen. Brach an einer anderen Stelle: Kurze Events können hochrelevant sein (eine Zusammenfassungszeile aus einem Stack-Trace), lange können Füllmaterial sein (ein Config-Dump). Token-Anzahl ist kein Signal für Relevanz. Umgeschwenkt auf einen inhaltsbasierten Filter bei der Aufnahme. Etwa zwei Stunden nach dem Umschwenken lief es.
Ein Absatz. Keine Überschriften. Die Struktur tragen die Verben (versucht, brach, umgeschwenkt), nicht die Abschnittsbezeichnungen. Die Lektion, falls es eine gibt, steckt im letzten Satz: Die Token-Anzahl ist ein verlockender Ersatz für Relevanz, aber ein falscher. Das war’s. Keine Überschrift „Lessons Learned“, keine Aufzählungspunkte.
Ich stellte den Entwurf auf fließende Prosa in der ersten Person um. Einträge sollen sich lesen, als hätte sie ein Entwickler geschrieben, denn genau das macht sie auch Monate später noch lesenswert.
Das Erfassungsproblem
Der zweite Irrweg war die Annahme, Claude könne Einträge einfach dann schreiben, wenn ihm etwas auffällt, das festhaltenswert ist. Mitten in der Session, nach einem Kurswechsel, am Ende einer Session: Das Modell könnte das selbst entscheiden.
Das funktioniert nicht. Es gibt zwei Fehlermodi, die in entgegengesetzte Richtungen ziehen. Beim ersten entscheidet das Modell, dass nichts festhaltenswert ist, und schreibt nichts. Das ist der Normalfall, wenn man einen Agenten bittet, „an X zu denken“, während er gerade mit Y beschäftigt ist. Beim zweiten protokolliert das Modell alles, mechanisch, jeden erfolgreichen Testlauf und jede Dateiänderung. Beides ergibt ein Tagebuch, das niemand liest.
Was Sie wirklich wollen, ist eine deterministische Erfassung der rohen Events und eine vom Urteilsvermögen getragene Synthese zu Prosa. Das sind verschiedene Aufgaben, und dafür sollten verschiedene Dinge zuständig sein.
Claude Code hat Hooks. Hooks feuern bei Lifecycle-Events: PostToolUse nach jedem Tool-Aufruf, UserPromptSubmit, wenn der Benutzer etwas eintippt, SubagentStop, wenn eine Sub-Agent-Aufgabe zurückkommt, und eine Handvoll weiterer. Sie führen Shell-Befehle aus, keine Modellaufrufe. Sie laufen jedes einzelne Mal, wenn ihre Bedingungen erfüllt sind, unabhängig davon, was das Modell entscheidet. Sie sind die deterministische Schicht.
Also schreiben Hooks die Events in ein strukturiertes Log: append-only, ein JSON-Objekt pro Zeile, in .dev-diary/.events.jsonl. Das Modell entscheidet nie, ob protokolliert wird; es passiert einfach. Die Synthese ist Aufgabe des Modells, manuell per Slash-Command am Ende einer Session aufgerufen, solange die vollständige Denkspur noch im aktiven Kontextfenster liegt.
Die events.jsonl sagt Ihnen mit Zeitstempeln, was passiert ist. Der Session-Kontext sagt Ihnen, warum und wie. Zusammen erlauben sie dem Modell, etwas Lesbares zu schreiben.
Inline oder aufgeschoben
Die letzte Spannung im Entwurf war der Zeitpunkt der Synthese. Zwei Optionen.
Inline: Der Benutzer tippt am Ende einer Session /diary, und Claude schreibt den Eintrag, mit der vollständigen Denkspur noch im aktiven Kontext. Die Textur des Warum steht direkt im Gespräch. Aufgeschoben: Der SessionEnd-Hook löst einen kleinen Hook vom Typ Prompt aus, der allein aus der events.jsonl synthetisiert, oder alternativ liest die erste Runde der nächsten Session die Events der vorherigen und schreibt den Eintrag rückblickend.
Die aufgeschobene Variante ist verlockend, weil sie am Ende der Session nicht um die Aufmerksamkeit des Benutzers konkurriert und weil frischer Kontext sauberere Prosa ergibt. Aber die aufgeschobene Variante hat nur das Event-Log, nicht die Denkspur. Das Event-Log sagt Ihnen, welche Dateien bearbeitet wurden und welche Befehle mit welchen Exit-Codes liefen; es sagt Ihnen nicht, dass ich einer Designentscheidung widersprochen und in eine andere Richtung gelenkt habe oder dass Claude Ansatz A erwogen, skizziert und verworfen hat, bevor es zu Ansatz B kam.
Diese Textur lebt nur im aktiven Kontext. Also gewann inline: manueller Aufruf von /diary, solange die Session noch lebt, mit dem Event-Log als einer Quelle unter mehreren und dem Gespräch selbst als der anderen. Die Hooks erfassen die Events die ganze Zeit über deterministisch, sodass der Audit-Trail selbst dann für eine spätere Rekonstruktion bereitliegt, wenn /diary nie eingetippt wird.
Das schließt auch einen automatischen Synthetisierer bei SessionEnd aus, der das naheliegende Nice-to-have gewesen wäre. Wenn SessionEnd feuert, ist die Haupt-Session schon weg. Ein Hook vom Typ Prompt synthetisiert dann aus einem ausgedünnten Kontext, und das ergibt genau das Gefühl eines automatisch generierten Changelogs, das ich vermeiden wollte.
Ausgeliefert
Der Skill liegt unter ikangai/claude-skills/diary. Das Ganze besteht aus einer SKILL.md (Regeln zum Tonfall, Synthese-Workflow, Entscheidungsregel für den Aufruf), einem Bash-Skript (log-event.sh, gut neunzig Zeilen, defensiv geschrieben, endet bei jedem Fehlermodus mit Exit-Code null, damit ein falsch konfigurierter Hook nie eine Claude-Code-Session kaputt macht) und drei Referenzdokumenten (Beispiele zum Tonfall, Hook-Einrichtung, Event-Schema).
Fünf Hook-Events werden erfasst: Write/Edit/MultiEdit (Zustandsänderungen an Dateien), Bash (Befehle und Exit-Codes, denn Fehlschläge sind die Momente, die sich später zu erzählen lohnen), UserPromptSubmit (Feedback und Kurskorrekturen des Benutzers), SubagentStop (Rückmeldungen von Sub-Agenten) und Stop (die letzte Nachricht einer Runde, optional). Read, Grep, Glob, LS werden bewusst nicht erfasst: Das ist Erkundung, keine Erzählung. Sie mitzuschreiben würde das Event-Log unter Rauschen begraben.
Lange Felder werden bei fünfhundert Zeichen abgeschnitten. Das Skript packt jede Hook-Payload in einen normalisierten Umschlag und schreibt eine Zeile nach .dev-diary/.events.jsonl. Fehlt jq, protokolliert es ein Sentinel-Event mit "error": "jq_not_installed", sodass die fehlende Abhängigkeit sichtbar wird, ohne dass etwas kaputtgeht. Das ganze Skript passt auf einen Bildschirm.
Das Tagebuch selbst liegt unter .dev-diary/ im Projektstamm, standardmäßig per gitignore ausgeschlossen. Einträge heißen YYYY-MM-DD-<slug>.md. Der Audit-Trail ist .events.jsonl. Die Synthese liest beides (die Events verankern die Zeitachse, die aktive Session liefert die Textur) und schreibt einen Absatz Prosa in der ersten Person und der Vergangenheit, mit dem Lektionssatz am Ende, falls er verdient ist.
Das Tagebuch wird seine eigene Weiterentwicklung dokumentieren. Selbstbezüglichkeit dieser Art ist nur dann nützlich, wenn sie tatsächlich funktioniert, also werde ich es herausfinden. v0 ist ausgeliefert; wenn keine Einträge mehr entstehen oder nur noch schlechte, muss am Skill selbst gearbeitet werden, diese Arbeit wird im Tagebuch dokumentiert, und diese Dokumentation wird der erste echte Test dafür sein, ob das alles eine gute Idee war.
Aus dem Englischen übersetzt: zum Originalbeitrag