All posts
Long-form notes on software, distributed systems, and the craft of building. Shipping one a week.
Code Graphs for Coding Agents: The Delivery Shape Matters More Than the Algorithm
I spent a weekend pointing a coding agent at a 480k-line Go monorepo and watching it grep-loop through 38 tool calls on one question. AST-derived code graphs fix that, but the delivery shape — local stdio MCP, remote service, or skill — changes the economics more than the graph algorithm does. Here is where I would put one in 2026, with a minimal Go indexer I can drop next to the agent.
AckWait Is a Contract: How a 30-Second Default Took Down My JetStream Consumer
I lost an evening to a NATS JetStream pull consumer that doubled its work in production. The cause was three lines of ConsumerConfig I never wrote. These are my notes on what AckWait actually counts, why MaxDeliver = -1 is the silent footgun, and the 70-line Go contract I now ship on every JetStream consumer.
Idempotency Is a Protocol, Not a Key
The first time I shipped idempotency as a UUID header and a Redis lookup, a duplicate charge slipped through a week later. These are my notes on treating idempotency as a four-part protocol — dedup, determinism, concurrent safety, downstream propagation — with a minimal Kotlin plus Postgres implementation that holds up under retry.
What `dbos ontime` Actually Asks: Building a Distributed Cron on etcd Leases in Go
A 0-click query for `dbos ontime` showed up in my Search Console last week. The reader is not asking about DBOS — they are asking how to run a job every minute, exactly once, across a fleet. From my own notes, an etcd lease, the `concurrency.Election` package, and a fencing token cover that case in under 100 lines of Go, without pulling in a workflow engine.
Event-Log-as-Source-of-Truth Turns Schema Evolution Into a Forever Problem
When the log is the source of truth, every schema change is permanent. A Kotlin/Avro walkthrough of the rename that passed the Schema Registry check and silently corrupted every old event, plus the Protobuf and Avro invariants I now keep pinned above my desk.
Turning LLM Context Engineering Into an Evaluation Loop with DSPy
Notes from two weekends of digging into DSPy. I stopped treating prompts as the source of truth and started treating them as compiled output from a typed signature, a metric, and an optimizer. Here is the smallest end-to-end program I kept, how MIPROv2 actually searches, and where the approach breaks down in practice.
Exposing Spring AI Agents via the A2A Protocol: What Interoperability Actually Buys You
Spring AI's server-side A2A integration is stable enough to put in production, but the protocol is most useful at organizational boundaries, not as an internal RPC replacement. This post walks through what actually changes in a Spring AI codebase, where the sharp edges still are, and a practical decision framework for A2A vs MCP vs plain REST.
DBOS vs Temporal: When Postgres Is Enough for Durable Workflow Execution
DBOS reuses Postgres as the durability layer for workflows, while Temporal runs a dedicated cluster. The right choice depends on team size, workload shape, and where you want your operational budget to go. This is a practical rubric for picking between them.
Cell-Based Architecture Isn't Free: What Slack, DoorDash, and Roblox Actually Paid For It
Cell-based architecture contains blast radius, but it is not free. A look at what Slack, DoorDash, and Roblox actually paid for cells in production — and a checklist for the cheaper fault-isolation patterns most teams should reach for first.
JetBrains Tracy: Pragmatic AI Observability for Kotlin
JetBrains Tracy is a Kotlin library that wires LLM-aware tracing into your app on top of OpenTelemetry. This post walks through how I integrated it in a Spring Boot service, the design decisions that matter, and the failure modes teams hit once LLM calls become the hottest path in their system.