<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Kevin Aspesi — Writing</title><description>Writing on iOS, agents, and dev tooling.</description><link>https://aspesi.dev/</link><item><title>Teaching Claude Code to review its own PRs</title><link>https://aspesi.dev/writing/teaching-claude-code-to-review-its-own-prs/</link><guid isPermaLink="true">https://aspesi.dev/writing/teaching-claude-code-to-review-its-own-prs/</guid><description>A judge agent, two independent reviewers, and a rule file per repo. What a self-review pipeline catches, what it confidently invents, and the prompt changes that closed the gap.</description><pubDate>Sun, 28 Jun 2026 00:00:00 GMT</pubDate></item><item><title>A worktree-per-agent workflow for parallel development</title><link>https://aspesi.dev/writing/a-worktree-per-agent-workflow/</link><guid isPermaLink="true">https://aspesi.dev/writing/a-worktree-per-agent-workflow/</guid><description>Give every agent its own git worktree and most coordination problems dissolve. Setup scripts, port allocation, and the cleanup step everyone forgets.</description><pubDate>Fri, 12 Jun 2026 00:00:00 GMT</pubDate></item><item><title>LangGraph checkpoints as a debugging superpower</title><link>https://aspesi.dev/writing/langgraph-checkpoints-as-a-debugging-superpower/</link><guid isPermaLink="true">https://aspesi.dev/writing/langgraph-checkpoints-as-a-debugging-superpower/</guid><description>Checkpoints aren&apos;t just resumability — they&apos;re a time machine. Replaying a misbehaving agent from any node, diffing state between runs, and the checkpointer I ended up writing.</description><pubDate>Sat, 30 May 2026 00:00:00 GMT</pubDate></item><item><title>SwiftUI&apos;s Observation framework, one year in</title><link>https://aspesi.dev/writing/swiftui-observation-framework-one-year-in/</link><guid isPermaLink="true">https://aspesi.dev/writing/swiftui-observation-framework-one-year-in/</guid><description>What @Observable fixed, the re-render traps that survived the migration, and the measurement setup I use before trusting any performance claim.</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate></item><item><title>The case for boring test infrastructure</title><link>https://aspesi.dev/writing/the-case-for-boring-test-infrastructure/</link><guid isPermaLink="true">https://aspesi.dev/writing/the-case-for-boring-test-infrastructure/</guid><description>Clever test frameworks rot faster than the code they test. Why I keep choosing flat fixtures, real assertions, and one slow end-to-end suite over anything exciting.</description><pubDate>Wed, 29 Apr 2026 00:00:00 GMT</pubDate></item><item><title>Writing an MCP server a model will actually use correctly</title><link>https://aspesi.dev/writing/writing-an-mcp-server-a-model-will-use-correctly/</link><guid isPermaLink="true">https://aspesi.dev/writing/writing-an-mcp-server-a-model-will-use-correctly/</guid><description>Tool descriptions are prompts, and most MCP servers write them like API reference docs. Naming, argument shape, and error strings that steer a model back on task instead of into a retry loop.</description><pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate></item><item><title>Evals for agents that edit code</title><link>https://aspesi.dev/writing/evals-for-agents-that-edit-code/</link><guid isPermaLink="true">https://aspesi.dev/writing/evals-for-agents-that-edit-code/</guid><description>Diffing against a golden patch is the wrong metric — a real edit has many correct shapes. The rubric I settled on, why I run every suite twice, and how much variance to tolerate before calling it a regression.</description><pubDate>Wed, 18 Mar 2026 00:00:00 GMT</pubDate></item><item><title>The actor boundary is a design decision, not a compiler chore</title><link>https://aspesi.dev/writing/the-actor-boundary-is-a-design-decision/</link><guid isPermaLink="true">https://aspesi.dev/writing/the-actor-boundary-is-a-design-decision/</guid><description>Strict concurrency doesn&apos;t just want annotations — it wants you to decide what your app&apos;s isolation model actually is. Three refactors where the red diagnostics were right and my architecture was wrong.</description><pubDate>Sat, 21 Feb 2026 00:00:00 GMT</pubDate></item><item><title>Stop reaching for `as`: `satisfies` and the shape of your config</title><link>https://aspesi.dev/writing/satisfies-and-the-shape-of-your-config/</link><guid isPermaLink="true">https://aspesi.dev/writing/satisfies-and-the-shape-of-your-config/</guid><description>A type assertion is the point where TypeScript stops helping you. How `satisfies` plus a couple of narrow generics let a config object check itself — and the two places I still cast and say so in a comment.</description><pubDate>Tue, 27 Jan 2026 00:00:00 GMT</pubDate></item><item><title>Snapshot tests I don&apos;t regret</title><link>https://aspesi.dev/writing/snapshot-tests-i-dont-regret/</link><guid isPermaLink="true">https://aspesi.dev/writing/snapshot-tests-i-dont-regret/</guid><description>Most SwiftUI snapshot suites become a wall of noise nobody reads. Pinning the device matrix, testing states instead of screens, and deleting every test that only ever failed on a system font update.</description><pubDate>Tue, 09 Dec 2025 00:00:00 GMT</pubDate></item><item><title>git rerere, or how I stopped re-solving the same conflict</title><link>https://aspesi.dev/writing/git-rerere/</link><guid isPermaLink="true">https://aspesi.dev/writing/git-rerere/</guid><description>One config flag turns a long-lived branch from a rebase tax into a non-event. What rerere records, the one case where its memory betrays you, and how it changed how long I let a branch live.</description><pubDate>Tue, 11 Nov 2025 00:00:00 GMT</pubDate></item><item><title>Structured output beat every prompt trick I tried</title><link>https://aspesi.dev/writing/structured-output-beat-every-prompt-trick/</link><guid isPermaLink="true">https://aspesi.dev/writing/structured-output-beat-every-prompt-trick/</guid><description>Months of prompt tuning to stabilize one agent&apos;s output, undone in an afternoon by a Zod schema. Where schema-constrained generation is a free win, and where it quietly costs you reasoning quality.</description><pubDate>Mon, 06 Oct 2025 00:00:00 GMT</pubDate></item><item><title>CLAUDE.md is a product surface</title><link>https://aspesi.dev/writing/claude-md-is-a-product-surface/</link><guid isPermaLink="true">https://aspesi.dev/writing/claude-md-is-a-product-surface/</guid><description>Written like documentation, an agent instruction file gets long and ignored. Written like an API — few rules, each testable, each naming the failure it prevents — it starts doing work.</description><pubDate>Tue, 19 Aug 2025 00:00:00 GMT</pubDate></item><item><title>Shipping a SwiftUI app with no view-model layer</title><link>https://aspesi.dev/writing/shipping-a-swiftui-app-with-no-view-model-layer/</link><guid isPermaLink="true">https://aspesi.dev/writing/shipping-a-swiftui-app-with-no-view-model-layer/</guid><description>I cut MVVM out of a real app to find out what would break. Mostly nothing — but the two places it genuinely hurt are worth knowing before you copy the experiment.</description><pubDate>Tue, 24 Jun 2025 00:00:00 GMT</pubDate></item></channel></rss>