Dialogues
April 19, 2026
What does it means to “publish” a blog post anymore? Once published, a post represents what I thought on that date. The back catalog is stale. But I keep musing and updating my thinking. Open source business models, growth engineering, customer engineering---these are conversations I’ve been having for years, with different people, and yet my posts remain frozen. Fine, if you think of a blog as a log, but what is that like for a new person (or agent) getting acquainted with me?
I wanted two things. First, the ability to resume a topic. Not write a new post that vaguely references an old one, but actually pick up where I left off, with the latest version always being my current thinking. Second, I wanted the process visible. Not just what I think now, but how I got here---which conversations changed my mind, which prompts from Claude sharpened an argument, which coffee chat made me rethink a paragraph.
The writing dialogue on my recent posts already showed the prompt-by-prompt drafting process with Claude. But those were stored as giant YAML files alongside each post---a parallel data structure that duplicated the content and had to be maintained separately. It worked, but it was brittle and manual.
Then I realized: git already tracks exactly what I want. Every edit to a post is a commit. The commit message can carry metadata---who I was talking to, what prompted the change, what type of input it was. The diff between commits is the evolution. I was maintaining a second system to track something my first system already did.
How it works
A dialogue is just a markdown file with a git history. Each commit that changes the file is an entry. The commit message carries structured metadata as git trailers:
I think taste and legibility are one and the same actually
taste is judged by other humans. legibility is convincing
other humans that you have taste.
With: Claude
The With: trailer names who or what precipitated the change---could be Claude, could be Sarah Chen <[email protected]>, could be Paul Graham. Commits without a With: trailer still show up in the timeline, but only as dates---silent edits with visible diffs.
The build pipeline
At build time, a script walks git log for each post file, parses the trailers, extracts the content at each commit, and writes a JSON file. Astro reads that JSON to render the dialogue viewer---the side panel on posts and the full /writing/{slug}/ pages.
The script caches against the latest commit hash per file, so npm run dev stays fast on repeat starts. In CI, the GitHub Actions workflow checks out with full history (fetch-depth: 0) and generates fresh.
A prepare-commit-msg git hook pre-fills the trailer template when I commit a post file, so I don’t have to remember the format.
Why not a database? Why not YAML? Why git?
Because the data is the history. Every version control system already stores exactly this---who changed what, when, and why. Adding a database or sidecar file to track changes to a file that’s already tracked by git is a category error. The commit message is the natural place for metadata about a change. The diff is the natural representation of what changed. I was building a shadow of a system I already had.
The tradeoff is commit message discipline. Every meaningful edit needs a well-written message with the metadata trailers. That’s a real cost. But it’s also a forcing function---it makes me think about why I’m changing something, not just what I’m changing. The git log becomes a publication artifact, not just a development tool.
A post is the beginning of a conversation
Grok on X must cost a fortune to run. It’s also easily the most valuable feature that platform has ever shipped---every tweet becomes a starting point, and you can pull a real back-and-forth into public view by just asking. Dialogues should be similar.
A post is still a post: a coherent unit of thought. But the path to it is continuous. You evolve. Which probably means post URLs are commit-tagged---/customer-engineering is just the latest, the way main is a named pointer that auto-advances. Permalinks live at the SHA.
And then what is a blog post? Mostly a soliloquy---an internal conversation made public. What makes it a dialogue is the (hopefully tasteful) addition of AI.
I think I actually missed on the first cut. I focused on the AI chat itself, which is honestly not that interesting, for the same reason most podcasts aren’t: they’re not well thought out.
What I want: direct editing, but on save AI immediately gives feedback on your changes and on the coherency of the post. It adds to the dialogue on the side, and its notes highlight the parts of the post they’re about. You chat back, voice or text. Publishing updates the post and summarizes the conversation behind the change.
One of the more boring things about blogs is the lack of public discourse. Comments don’t fix it---why craft a beautiful thought in someone else’s comment section, to be read by 1% of an already-small readership? Better to link out to your public platform, where the conversation is happening anyway.

