<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peter van Onselen</title>
    <description>The latest articles on DEV Community by Peter van Onselen (@peter_vanonselen_e86eab6).</description>
    <link>https://dev.to/peter_vanonselen_e86eab6</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3591718%2Fc6221dff-fdf2-4d07-be3a-079fda12003b.jpg</url>
      <title>DEV Community: Peter van Onselen</title>
      <link>https://dev.to/peter_vanonselen_e86eab6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peter_vanonselen_e86eab6"/>
    <language>en</language>
    <item>
      <title>The AI Dev Tooling Setup I Actually Recommend to Coworkers (Early 2026)</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Mon, 30 Mar 2026 07:56:07 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/the-ai-dev-tooling-setup-i-actually-recommend-to-coworkers-4mom</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/the-ai-dev-tooling-setup-i-actually-recommend-to-coworkers-4mom</guid>
      <description>&lt;p&gt;A coworker asked me how to get started with AI tooling, and I realised my answer might be useful to others. Here's roughly how I think about it as of early 2026. &lt;/p&gt;

&lt;p&gt;𝗧𝗲𝗿𝗺𝗶𝗻𝗮𝗹-𝗯𝗮𝘀𝗲𝗱 𝗔𝗜 𝗮𝗴𝗲𝗻𝘁𝘀 (𝗽𝗶𝗰𝗸 𝗼𝗻𝗲)&lt;br&gt;
At a bare minimum, ditch VS Code Copilot and get OpenCode. You can log into Copilot through OpenCode and you get a genuinely decent AI agent harness without all the VS Code bloat. Otherwise, install Codex CLI or Claude Code, whichever you have access to. If you go with Claude Code, look into the skills and extensions available.&lt;/p&gt;

&lt;p&gt;No matter which CLI tool you use, investigate the PRD skill from the Ralph Wingham loop (&lt;a href="https://github.com/snarktank/ralph" rel="noopener noreferrer"&gt;https://github.com/snarktank/ralph&lt;/a&gt;). It's really cool.&lt;/p&gt;

&lt;p&gt;𝗚𝗶𝘁 𝘄𝗼𝗿𝗸𝘁𝗿𝗲𝗲𝘀&lt;br&gt;
Spend some time learning git worktrees. They are a lifesaver when working with long-running agents in terminals. Write yourself a script that lets you create or switch to a worktree quickly. Here is one that I hacked together that makes it abundantly easier than the existing git worktree commandline: (&lt;a href="https://github.com/vanonselenp/dotfiles/blob/main/gz.zsh" rel="noopener noreferrer"&gt;https://github.com/vanonselenp/dotfiles/blob/main/gz.zsh&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;𝗖𝗼𝗻𝘁𝗲𝘅𝘁 𝗴𝗮𝘁𝗵𝗲𝗿𝗶𝗻𝗴 (𝘁𝗵𝗶𝘀 𝗶𝘀 𝘁𝗵𝗲 𝗯𝗶𝗴 𝗼𝗻𝗲)&lt;br&gt;
If you have access to ChatGPT or Claude.ai, connect every internal tool and system your organisation offers. These platforms can scan across Google Drive, Confluence, Jira, and other sources to assemble the context you need when working on something new. It's a massive time saver.&lt;/p&gt;

&lt;p&gt;Also, if you're in meetings with Gemini (or any tool that supports it), keep your transcripts. They're incredibly useful for generating additional context later.&lt;/p&gt;

&lt;p&gt;𝗢𝗻𝗲 𝗹𝗮𝘀𝘁 𝘁𝗶𝗽&lt;br&gt;
Skip the GitHub MCP. Your agent already knows how to use the GitHub CLI, and it won't pollute your context window the way MCP integrations tend to.&lt;/p&gt;

&lt;p&gt;That should be enough to get started. Happy to answer questions in the comments.&lt;/p&gt;

&lt;p&gt;PS: if you happen to find a good cli for accessing Confluence and Jira, let me know!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>cli</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>The Smell of Panic When You Context Thrash</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Tue, 24 Mar 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/the-smell-of-panic-when-you-context-thrash-3mop</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/the-smell-of-panic-when-you-context-thrash-3mop</guid>
      <description>&lt;p&gt;&lt;em&gt;High high hope for the code, shooting for a PR when I couldn’t even make a commit…&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.petervanonselen.com%2Fassets%2Fpanic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.petervanonselen.com%2Fassets%2Fpanic.png" alt="Panic at the keyboard" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over the past few weeks I have been increasingly panicked. That’s probably the only honest way to frame it.&lt;/p&gt;

&lt;p&gt;I’ve been juggling a lot. Supporting a team building out a new payment method. Handing over deep knowledge of an existing payment method to another team working outside our scope but integrating with systems we own. Helping yet another team figure out how to break a backend platform service from a monolith into microservices. And somewhere in between all of that, trying to actually deliver a feature myself: a seemingly straightforward change to one of our frontend purchase journeys to make it faster.&lt;/p&gt;

&lt;p&gt;Each of those things individually requires serious context. Together they’ve been chewing up my headspace and pulling me in every direction. Which means that whenever I finally sat down to write actual code, I arrived in a state of absolute panic. The “oh my gosh I have so little time, move quickly, move quickly, move quickly” kind of survival mode.&lt;/p&gt;

&lt;p&gt;And that’s when I made one of the most fundamental mistakes you can make with AI-assisted development.&lt;/p&gt;

&lt;h2 id="the-50-file-disaster"&gt;The 50-File Disaster&lt;/h2&gt;

&lt;p&gt;Here’s the thing about AI-generated code: it’s easy. So easy that it’s almost impossible to remember just how easy it is, because you’ve spent a lifetime handcrafting code yourself. You carry this default assumption that building things is complicated and slow.&lt;/p&gt;

&lt;p&gt;So I did what I thought was the right thing. I planned. I looked through the existing code. I thought about it. I wrote out detailed acceptance criteria. I thought about the problem from the AI’s perspective. And then I said “cool, I think I have enough” and started implementing.&lt;/p&gt;

&lt;p&gt;By the time I got someone else to look at it, they pointed out it was missing a key behaviour. I’d misunderstood part of the acceptance criteria. OK, fine. I started trying to fix it.&lt;/p&gt;

&lt;p&gt;And then trying to fix it. And trying to fix it.&lt;/p&gt;

&lt;p&gt;What was a small hole became a deep hole became a nightmare became “why does it feel like I will never, ever get anywhere with this?” By the end of it I was touching something like 50 files across two repos. Small changes scattered everywhere, most of them not even really needed. All driven by the panic override of needing to get something done while constantly being pulled out of context and back in and out and back in until I was just thrashing. Burning cycles. Making zero progress.&lt;/p&gt;

&lt;h2 id="panic-is-a-smell"&gt;Panic Is a Smell&lt;/h2&gt;

&lt;p&gt;If you’ve been in software long enough you know what a code smell is. Something that isn’t technically broken but tells you something deeper is wrong.&lt;/p&gt;

&lt;p&gt;The panic to get things done is a smell. The pushing and pushing and pushing is a smell. The feeling that you don’t have enough time, that you have to ship something right now, that you can’t afford to slow down? That’s a smell. And I ignored it for way too long.&lt;/p&gt;

&lt;p&gt;Because here’s the lesson I apparently need to keep re-learning: with AI-assisted development, &lt;em&gt;the writing of code is not the bottleneck&lt;/em&gt;. It never was. The understanding is the bottleneck. And when you’re panicking, you skip the understanding to get to the doing, which is exactly backwards.&lt;/p&gt;

&lt;h2 id="the-reset"&gt;The Reset&lt;/h2&gt;

&lt;p&gt;I eventually stopped. Stepped away from the mess. Started with a brand new repository. Took all the things I’d learned, the plan document, the acceptance criteria, everything. And then I spent an entire day in conversation with an AI. Not writing code. Just investigating.&lt;/p&gt;

&lt;p&gt;Testing existing behaviour. Running multiple examples and execution paths. Making sure I had a precise, clear understanding of what the current system actually did, what the new behaviour needed to be, and all the various paths between them. I literally spent hours asking the AI to explain each step of its plan and justify why it chose that approach.&lt;/p&gt;

&lt;p&gt;I say all the time that planning matters more than coding. But experiencing the contrast firsthand is different. Hours of slow, methodical, back-and-forth investigation. Deep thinking about context. Deep thinking about what you’re trying to do and why. So that when you, &lt;em&gt;the human in the loop&lt;/em&gt;, actually ask the AI to build something, the full context of what you’re trying to achieve is sitting clearly in your head. You understand the user behaviour. The system interactions. The high-level architecture. You could draw all the diagrams because you actually understand what needs to be done.&lt;/p&gt;

&lt;p&gt;The feature that had consumed a week and a half of thrashing? After that day of planning, it took a couple of hours to get something working correctly.&lt;/p&gt;

&lt;h2 id="the-council-of-ais-or-going-wide"&gt;The Council of AIs (or: Going Wide)&lt;/h2&gt;

&lt;p&gt;Meanwhile, on the other side of my work life, I’ve been doing something completely different with AI tooling.&lt;/p&gt;

&lt;p&gt;To support the contracting team building out a new feature, I’ve been running what is essentially a council of AIs to review their design documents. OpenCode, Codex CLI, and Claude Code running simultaneously so I can verify, validate, and cross-compare. Deep-dive analysis with Claude and ChatGPT for architectural decisions and historical context. Complex investigation into bugs that were first logged two years ago and never properly resolved.&lt;/p&gt;

&lt;p&gt;I have been holding the context of a massive amount of different workstreams. Work that would have taken me days or weeks to get even a baseline understanding of. The AI tooling genuinely lets you go wide in a way that wasn’t possible before.&lt;/p&gt;

&lt;p&gt;And that’s where the tension lives.&lt;/p&gt;

&lt;h2 id="shield-and-sword"&gt;Shield and Sword&lt;/h2&gt;

&lt;p&gt;The honest truth is that I’ve been doing two very different jobs at the same time.&lt;/p&gt;

&lt;p&gt;One job is the shield: absorbing context, running investigations, unblocking other teams, reviewing designs, holding the big picture so nobody else has to. The AI tooling makes this possible. It lets you hold 10x the context. You can pre-empt meetings by using Claude to pull together context and solve problems before the meeting even happens, cancelling two or three in a morning and buying yourself hours of uninterrupted time. You can run parallel investigations across multiple tools and hold the full picture of what’s going on across an entire programme of work.&lt;/p&gt;

&lt;p&gt;The other job is the sword: actually sitting down and delivering a piece of working software. And that requires the opposite of going wide. It requires going deep. Slow. Methodical. Boring, even.&lt;/p&gt;

&lt;p&gt;The AI enables both.&lt;/p&gt;

&lt;p&gt;But your brain can’t do both at the same time.&lt;/p&gt;

&lt;p&gt;When you try, you thrash. You burn cycles switching between deep and wide, and just like a thrashing computer, you end up doing a lot of work and making no progress.&lt;/p&gt;

&lt;h2 id="what-im-taking-away"&gt;What I’m Taking Away&lt;/h2&gt;

&lt;p&gt;Two things, and they’re in tension with each other, and I’m OK with that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go deep before you go fast.&lt;/strong&gt; Planning with AI isn’t just “write a spec and hand it over.” It’s hours of investigation. It’s asking the AI to explain its own plan in painful detail. It’s making sure you understand the problem so well you could solve it by hand. The code is the easy part. The understanding is the work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI lets you hold a lot of context, but your brain still has limits.&lt;/strong&gt; Context switching costs the same as it always did. Maybe more, because the AI makes it tempting to take on everything. You can hold the shield and the sword, but not at the same time. Deliberately buying yourself blocks of deep time is not optional. It’s the whole game.&lt;/p&gt;

&lt;p&gt;This is the new trap for senior engineers. AI lets you take on more surface area than ever before. But the work that actually ships still requires deep focus. Nobody is immune to thrashing, no matter how good the tooling gets.&lt;/p&gt;

&lt;p&gt;And if you’re sitting there right now, pushing and pushing and panicking and feeling like you’ll never get there? That’s a smell. Stop. Step away. Start again with understanding, not urgency.&lt;/p&gt;

</description>
      <category>aios</category>
      <category>claudecode</category>
      <category>softwarecraftsmanshi</category>
    </item>
    <item>
      <title>The Feedback That Doesn’t Care About Your Title</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Tue, 17 Mar 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/the-feedback-that-doesnt-care-about-your-title-j2n</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/the-feedback-that-doesnt-care-about-your-title-j2n</guid>
      <description>&lt;p&gt;&lt;em&gt;What doesn’t kill you makes you stronger … right?&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;I’ve been writing this blog for a while now. I’ve documented scope creep spirals, the joy of deleting code I spent weeks writing, and the slow painful education of learning to work with AI agents without letting them run off a cliff. If you’ve been following along, you know the theme by now: I learn things the hard way and then write about it so you don’t have to. Or at least so you can watch.&lt;/p&gt;

&lt;p&gt;Yesterday I was explaining to a colleague how I use Gemini to give me personalised feedback on my performance after meetings. He’s a staff engineer, someone who’s genuinely deep into AI-assisted coding, not a tourist. And even he stopped and went: “Wait, you’re doing &lt;em&gt;what&lt;/em&gt;?”&lt;/p&gt;

&lt;p&gt;That reaction made me step back. Because I hadn’t really sat down and thought about what I’d actually built over the past year. I’d been solving problems one at a time, better code generation here, better context gathering there, a way to get honest feedback on myself over here, and somewhere along the way it had become something bigger. A system. A layer underneath how I work that I now can’t imagine working without.&lt;/p&gt;

&lt;p&gt;So this is me trying to describe what that looks like, now that I’ve finally noticed it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.petervanonselen.com%2Fassets%2Ffeedback-that-kills-you%2Fimage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.petervanonselen.com%2Fassets%2Ffeedback-that-kills-you%2Fimage.png" alt="the layers" width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="the-code-layer-get-off-the-autocomplete"&gt;The code layer: get off the autocomplete&lt;/h2&gt;

&lt;p&gt;If you’re writing code with an AI assistant inside your IDE, Copilot in VS Code for instance, I’d gently suggest you’re missing the better experience. CLI agents like Claude Code, Codex CLI, and Open Code have fundamentally changed how I interact with code. Open Code has become my go-to because it works well straight out of the box and, crucially, it connects to Copilot’s backend models. If your company already pays for Copilot, Open Code might be the unlock you didn’t know you were waiting for.&lt;/p&gt;

&lt;p&gt;The shift matters because it changes what the AI is doing. Inside an IDE, it’s autocomplete with delusions of grandeur, guessing what you want line by line. On the command line, I’m describing problems, analysing architecture, pulling systems apart, generating diagrams. It stops being a typing assistant and starts being a thinking partner.&lt;/p&gt;

&lt;p&gt;I use this for everything that touches code directly: writing it, reviewing it, debugging, breaking things apart to understand them, building architecture diagrams. The lot.&lt;/p&gt;

&lt;h2 id="the-context-layer-taming-the-organisational-scatter"&gt;The context layer: taming the organisational scatter&lt;/h2&gt;

&lt;p&gt;Every engineer in a large organisation knows this pain. The information you need to do your work lives in seven different places: Slack threads, Google Meet recordings, Confluence pages, Jira tickets, GitHub PRs, and at least two places nobody told you about. You spend half your time assembling a coherent picture before you can even start thinking.&lt;/p&gt;

&lt;p&gt;ChatGPT and Claude’s enterprise integrations have changed this for me. Both allow you to connect to corporate tools, your chat platform, docs, issue tracker, source control, and pull context into a single conversation. Instead of trawling through three Slack channels and two Confluence pages for forty minutes, I pull it all together and ask: what does this ticket actually need? What are the acceptance criteria? What am I missing?&lt;/p&gt;

&lt;p&gt;Here’s where it compounds. Good acceptance criteria from this layer mean better prompts for the coding agents. The layers feed each other. I didn’t design it that way, it just happened once the pieces were in place.&lt;/p&gt;

&lt;h2 id="the-mirror-feedback-that-doesnt-care-about-your-feelings"&gt;The mirror: feedback that doesn’t care about your feelings&lt;/h2&gt;

&lt;p&gt;This is the hard one to talk about. And the one that made my colleague stop in his tracks.&lt;/p&gt;

&lt;p&gt;We’re a remote organisation. Google Meet is where everything happens, and Gemini sits inside every meeting. Most people don’t turn on transcriptions, which I think is a mistake. Any meeting producing collective knowledge should generate a transcript. Those transcripts feed the context layer above.&lt;/p&gt;

&lt;p&gt;But there’s another use that took me months to work up to.&lt;/p&gt;

&lt;p&gt;After meetings where I’m an active participant, I ask Gemini: as a staff engineer, what went well, what didn’t go well, and what can I improve on?&lt;/p&gt;

&lt;p&gt;The first few times, it was rough.&lt;/p&gt;

&lt;p&gt;Here’s the thing about feedback from humans: you almost never get anything useful. You either get “yeah, that was fine” or something so carefully hedged that whatever kernel of truth was in there has been sanded down to nothing. I’ve rarely received feedback that was specific, actionable, and tied directly to something I actually did in a real moment.&lt;/p&gt;

&lt;p&gt;Gemini doesn’t do hedging. It references specific things that happened in the meeting. “You reframed the argument here and it shifted the conversation constructively.” Or: “You weren’t listening here and this is where it cost you.” It once told me that while I’d handled a frustrated colleague well, I could have spotted the frustration earlier and intervened before it escalated, and that when another colleague was dismissive, I’d recovered well but could have prepared for that reaction. Specific. Contextual. Minutes after it happened.&lt;/p&gt;

&lt;p&gt;When I explained this to my colleague yesterday, he asked: “Isn’t this just seeking perfection?” And I realised, no. It’s just a way to learn and grow and become more deliberate about how I communicate, how I lead, and how I interact with the people around me. You can’t improve what you don’t measure. This is measuring.&lt;/p&gt;

&lt;p&gt;But here’s what really made me think this is bigger than my own little experiment. I told a principal engineer friend at another company about this approach. He had a difficult conversation coming up, recorded it with Gemini, and afterwards used the transcript to get actionable feedback on how he’d handled it. His reaction was genuine shock. He’d never had that clear a picture of how his conduct was landing. An engineering manager I know has started doing the same thing and describes it as brutal but the most meaningful feedback he’s received in years.&lt;/p&gt;

&lt;p&gt;And I think there’s a reason for that. I remember chatting with a startup CEO at a meetup who made the observation that the higher you go in leadership, the less honest feedback you receive. The position of power makes it hard for people to cross that barrier. Gemini doesn’t have any concept of your title or your seniority. It just tells you what it saw.&lt;/p&gt;

&lt;p&gt;In the beginning, every session felt like a wake-up call. After months of doing this consistently, keeping a log, reading it back, it softened. Not because the feedback got less honest, but because the gap between what I thought I was doing and what I was actually doing got narrower. Fewer surprises. More gentle nudges, fewer gut punches.&lt;/p&gt;

&lt;h2 id="so-what-is-this-actually"&gt;So what is this, actually?&lt;/h2&gt;

&lt;p&gt;None of these tools alone would be worth a blog post. A CLI coding agent is nice. Enterprise AI integrations save time. AI self-reflection is powerful but weird. What caught me off guard, what I only noticed yesterday when I saw my colleague’s reaction, is that they work as a system.&lt;/p&gt;

&lt;p&gt;Meeting transcripts feed the context layer. The context layer produces better acceptance criteria. Better acceptance criteria drive better output from the coding agents. The self-improvement loop makes me more effective in the meetings that generate the transcripts. Each layer feeds the others. I didn’t plan it. I just kept solving problems and the connections emerged.&lt;/p&gt;

&lt;p&gt;There’s a Sam Altman interview from about a year ago where he describes people using AI as “an operating system for how they think.” At the time I had absolutely no idea what he meant. Now I think I do, and the uncomfortable truth is that I’m probably barely scratching the surface of where this goes.&lt;/p&gt;

&lt;p&gt;So here is my take away action for you. Next meeting you are in with a transcript, ask an LLM for some honest feedback. Let me know if you learn anything interesting!&lt;/p&gt;

&lt;p&gt;I’m still figuring it out. As usual, you’ll hear about it when I do.&lt;/p&gt;

</description>
      <category>aios</category>
      <category>claudecode</category>
      <category>softwarecraftsmanshi</category>
    </item>
    <item>
      <title>How I Learnt to Stop Worrying and Love Agentic Katas</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Thu, 05 Mar 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/how-i-learnt-to-stop-worrying-and-love-agentic-katas-1ob9</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/how-i-learnt-to-stop-worrying-and-love-agentic-katas-1ob9</guid>
      <description>&lt;p&gt;&lt;em&gt;I don’t know how to teach this. But I think I’ve figured out how to practice it…&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Have you ever struggled to get started with something new—not because the thing itself is hard, but because the &lt;em&gt;shape&lt;/em&gt; of how to learn it isn’t clear? That’s where I’ve been stuck with agentic coding. Not the doing of it. I’ve been doing it for months. The teaching of it. The “how do I help someone else get started” of it.&lt;/p&gt;

&lt;p&gt;And then I remembered code retreats. And katas. And the way I actually learned TDD all those years ago—not from a book, but from structured practice with low stakes and room to play.&lt;/p&gt;

&lt;p&gt;So I built a set of agentic katas: structured coding exercises designed specifically for practising AI-assisted development. Not traditional katas—those are too small and the AI already knows all the answers. These are bigger, meatier problems in unfamiliar domains that force you to engage with the full process of working alongside an agent.&lt;/p&gt;

&lt;p&gt;Let me explain how I got here.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Brief History of Practising on Purpose
&lt;/h2&gt;

&lt;p&gt;Early in my career, code retreats were the thing that taught me test-driven development. Not a book. Not a course. A structured, all-day event where you solve Conway’s Game of Life over and over again, each time with different constraints. Maybe your pair is actively trying to &lt;em&gt;not&lt;/em&gt; solve the problem. Maybe you’re strictly ping-ponging. Maybe you delete your code every 45 minutes.&lt;/p&gt;

&lt;p&gt;The point was never to solve Conway’s Game of Life. The point was to internalise the patterns and practices of TDD by giving yourself a safe space to experiment. No production pressure. No deadlines. Just play.&lt;/p&gt;

&lt;p&gt;Code katas grew out of the same ethos—small, self-contained problems that shouldn’t take more than an hour or two. The algorithm doesn’t matter. How you choose to solve it does. They’re bite-sized by design. They’re not supposed to be hard. They’re supposed to be &lt;em&gt;practice&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Katas and AI
&lt;/h2&gt;

&lt;p&gt;Here’s the thing I’ve been struggling with: traditional code katas don’t work for learning agentic development. They’re too small. The LLM has already seen every solution to FizzBuzz and Roman Numerals in its training data. You’re not practising a workflow—you’re watching an AI regurgitate a known answer. There’s nothing to explore, nothing to plan, no decisions to make about approach or tooling.&lt;/p&gt;

&lt;p&gt;And that matters, because the skill you need to develop with agentic coding isn’t “how to prompt an AI to write code.” It’s how to &lt;em&gt;think alongside one&lt;/em&gt;. How to explore a problem space together. How to write a plan that gives an agent enough context to be useful. How to verify that what came back is actually what you wanted. How to set up your workspace so the AI has the right guardrails.&lt;/p&gt;

&lt;p&gt;None of that shows up in a 30-minute kata where the AI already knows the answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Accidental Discovery
&lt;/h2&gt;

&lt;p&gt;What’s funny is that I’ve kind of been doing agentic katas already—almost by accident. I just didn’t realise it at the time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufyvpe4gyy5hgrtn7gzu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufyvpe4gyy5hgrtn7gzu.png" alt="The first kata" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few weeks ago I wrote about &lt;a href="https://dev.to/peter_vanonselen_e86eab6/this-is-the-way-delete-the-code-2n8m"&gt;deleting code on purpose as a way to recover from burnout&lt;/a&gt;. I’d been experimenting with the Ralph Wingum loop—throwing PRDs at an agentic coding workflow, seeing what came out, then deliberately throwing the code away. The output I was chasing wasn’t a codebase. It was understanding. How big can a PRD get before the loop breaks? How much do agent files matter? What’s the minimum setup to get something useful?&lt;/p&gt;

&lt;p&gt;Each run was a contained experiment. Fresh repo, clear problem, focused practice, delete the code, do it again. I was varying one thing at a time—adding a CLAUDE.md file, scaling up the PRD size, trying a different domain—and learning from each iteration.&lt;/p&gt;

&lt;p&gt;I was doing agentic katas. I just hadn’t named them yet.&lt;/p&gt;

&lt;p&gt;Looking back, the whole arc has been building toward this. My game project was the first rough version—months of cycling through spec-driven development and making mistakes. The “delete the code” experiments compressed that into focused sessions. And now, formalising the structure into something other people can pick up feels like the obvious next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Thing
&lt;/h2&gt;

&lt;p&gt;So I’ve put together a set of agentic katas. The idea is that each one should require somewhere in the region of four to eight hours of focused hand crafted work to do &lt;em&gt;well&lt;/em&gt;. And by “well” I mean the full golden plate: test-driven, 100% coverage, clean README, proper git history, the works. Not because the output matters—but because doing that level of work with an AI agent forces you to actually engage with the process.&lt;/p&gt;

&lt;p&gt;The loop for every kata is the same:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explore&lt;/strong&gt; → &lt;strong&gt;Plan&lt;/strong&gt; → &lt;strong&gt;Set Up Context&lt;/strong&gt; → &lt;strong&gt;Build&lt;/strong&gt; → &lt;strong&gt;Verify&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And there’s one key rule that makes the whole thing work: &lt;em&gt;you are not allowed to choose a programming language or framework until you’ve had a conversation with your AI tool about what the best approach is.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is the rule that forces the shift. Instead of jumping straight to “build me X in TypeScript,” you have to start with “I need to solve this problem—what are my options?” You explore the problem space. You figure out what tools exist. You have the AI challenge your assumptions. &lt;em&gt;Then&lt;/em&gt; you decide on an approach.&lt;/p&gt;

&lt;p&gt;From there, you write a detailed plan—acceptance criteria, example data, use cases, a breakdown into small chunks of work. You set up your workspace with an agent file and think about what context to include. You build incrementally. And you verify everything: read the plan, read the code, run it, test it, confirm it does what you intended.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.petervanonselen.com%2Fassets%2Fagentic-kata%2Fagentic-kata-loop.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.petervanonselen.com%2Fassets%2Fagentic-kata%2Fagentic-kata-loop.svg" alt="the loop" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Katas Themselves
&lt;/h2&gt;

&lt;p&gt;I’ve started with four problems, each chosen because they sit in a domain most developers haven’t worked in before:&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;audio transcriber&lt;/strong&gt; that handles speech-to-text with timestamps and speaker diarisation. A &lt;strong&gt;background remover&lt;/strong&gt; for image segmentation. A &lt;strong&gt;meme generator&lt;/strong&gt; that deals with text rendering and positioning on arbitrary images. And a &lt;strong&gt;thumbnail ranker&lt;/strong&gt; that scores images for visual appeal.&lt;/p&gt;

&lt;p&gt;Each kata has deliberate ambiguity baked in—because real problems are ambiguous, and part of the skill is figuring out what questions to ask. They also have a privacy constraint (everything runs locally, no cloud APIs for processing) and an extra credit extension for when you want to push further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters Right Now
&lt;/h2&gt;

&lt;p&gt;I’ll be honest: the reason I’m putting this together is partly selfish. I want to run a workshop with my colleagues, and I need structured material to do it. But there’s a bigger motivation too.&lt;/p&gt;

&lt;p&gt;Right now, everything about AI and software development feels incredibly intense. Fear of being made obsolete. AI layoff discourse everywhere. The pressure to have strong opinions about tools you’ve barely had time to evaluate. It’s all very stressful, and stress is the enemy of learning.&lt;/p&gt;

&lt;p&gt;What people actually need—what &lt;em&gt;I&lt;/em&gt; needed, and what I accidentally created for myself—is a safe space to play. A contained environment where you can try things, make mistakes, and build intuition without the stakes of production code or career anxiety hanging over you.&lt;/p&gt;

&lt;p&gt;Code retreats gave us that for TDD. I’m hoping agentic katas can do the same for working with AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Repo
&lt;/h2&gt;

&lt;p&gt;I’ve put everything together in a repo: &lt;a href="https://github.com/vanonselenp/agentic-katas" rel="noopener noreferrer"&gt;github.com/vanonselenp/agentic-katas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It includes the kata briefs, a participant guide covering the rules and process, and a facilitator guide for anyone who wants to run this as a structured session with their team. A session takes about 90 minutes.&lt;/p&gt;

&lt;p&gt;I haven’t run this with anyone else yet. I only put it together today, and I’m planning to trial it with my team in the coming weeks. It might be brilliant. It might be terrible. Either way, I’ll write about how it goes.&lt;/p&gt;

&lt;p&gt;But the core idea—that you need bigger, unfamiliar problems to practise AI-assisted development, and that the process matters more than the output—that I’m confident about. Because I’ve been living it, accidentally, for months.&lt;/p&gt;

&lt;p&gt;If you try it, I’d love to hear how it goes. And if you’re doing something different to build these skills, I’d love to hear about that too.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>specdrivendevelopmen</category>
      <category>katas</category>
      <category>softwarecraftsmanshi</category>
    </item>
    <item>
      <title>14 PRs, 6 Repos, 1 Button: A Tale of Tumbling Down the Rabbit Hole</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Thu, 12 Feb 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/14-prs-6-repos-1-button-a-tale-of-tumbling-down-the-rabbit-hole-3b7k</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/14-prs-6-repos-1-button-a-tale-of-tumbling-down-the-rabbit-hole-3b7k</guid>
      <description>&lt;p&gt;&lt;em&gt;True stories from the front lines of the internet…&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vlwivw6ea97d5ncnotq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vlwivw6ea97d5ncnotq.jpg" alt="Alice falling down the rabbit hole" width="800" height="600"&gt;&lt;/a&gt;&lt;em&gt;Alice in Wonderland by &lt;a href="https://commons.wikimedia.org/wiki/File:Down_the_Rabbit_Hole_(311526846).jpg" rel="noopener noreferrer"&gt;Valerie Hinojosa&lt;/a&gt; / &lt;a href="https://creativecommons.org/licenses/by-sa/2.0/" rel="noopener noreferrer"&gt;Creative Commons Attribution-Share Alike 2.0&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now this is a story all about how one button link got my codebase flipped turned upside down. And I’d like to take a minute, just sit right there, and I’ll tell you how I shipped 14 PRs without pulling out my hair.&lt;/p&gt;

&lt;p&gt;It started with a Monday morning meeting. I’d been off for three weeks. The meeting was dense with context about decisions made months ago, documented across scattered specs and design docs. Systems I don’t own. Plans originally speced out almost a year prior. SEO requirements. Legacy middleware behaviour. And somewhere in all of this, a single task: change where a subscribe button points.&lt;/p&gt;

&lt;p&gt;The old flow routed users through a legacy auth endpoint which was a piece of middleware handling user state and return-to-site functionality. The new flow should skip that layer and go direct. Simple, right?&lt;/p&gt;

&lt;p&gt;Three repos. 3 small PRs. That was the original scope.&lt;/p&gt;

&lt;p&gt;It became six repos and one or two more PRs…&lt;/p&gt;

&lt;h2&gt;
  
  
  The Context Problem
&lt;/h2&gt;

&lt;p&gt;Here’s what made this tricky: I didn’t have the context. Not the institutional knowledge of why things were built this way. Not the codebase familiarity to know where all the tendrils reached. Not the cross-system visibility to see how changes would ripple.&lt;/p&gt;

&lt;p&gt;Normally, this is where you’d involve other teams. Schedule alignment meetings. Negotiate architecture choices. Coordinate timed releases. The org chart becomes the constraint.&lt;/p&gt;

&lt;p&gt;Instead, I threw five AI tools at the problem.&lt;/p&gt;

&lt;p&gt;I used internal knowledge search to surface half a dozen docs from a year ago about what a potential migration might look like. Copilot and Codex scanned repos I’d never opened, outputting high-level analysis of what would need to change. NotebookLM synthesised a dozen-plus sources into actionable Jira tickets with acceptance criteria and testing plans. And Claude handled the actual implementation across all six repositories.&lt;/p&gt;

&lt;p&gt;Each tool for what it does best. None of them sufficient alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Shape of the Change
&lt;/h2&gt;

&lt;p&gt;What was supposed to be three repos became six because the AI tooling kept finding rabbit holes worth going down.&lt;/p&gt;

&lt;p&gt;The approach was backwards compatibility first. I updated the auth service to forward requests to the new endpoint, so existing systems would keep working. Only after that was stable did I remove the old code paths and switch the calls to point directly to the new flow.&lt;/p&gt;

&lt;p&gt;Along the way, I hit a referrer bug that only revealed itself mid-implementation. One of the components lived in a shared library, not a full application, which meant handling referral data differently than expected. This meant that I had to change how it was reading from window referrer data rather than relying on direct redirect URLs.&lt;/p&gt;

&lt;p&gt;And then there was a shared header component in another team’s repo. Hardcoded to the old endpoint. In code I couldn’t easily modify. The rabbit holes kept cropping up every time I thought I dived down them all.&lt;/p&gt;

&lt;p&gt;Fourteen PRs. Six repositories. Backwards compatible throughout. Zero downtime.&lt;/p&gt;

&lt;p&gt;The old flow had an extra hop through legacy middleware that handled state management. The new flow removes that layer entirely. Which makes for a faster time to checkout, same user experience, one less thing to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Point
&lt;/h2&gt;

&lt;p&gt;This would have been a multi-team effort. Alignment meetings across three teams, at minimum. Negotiated timelines. Architectural discussions. Coordinated releases.&lt;/p&gt;

&lt;p&gt;Instead, it was one developer holding context that used to require an org chart.&lt;/p&gt;

&lt;p&gt;I’m not saying AI tooling makes you a better engineer. I’m saying it lets you hold more context. And sometimes that’s the difference between “we’ll need to schedule a meeting with the other teams” and “I’ll have a PR up by Thursday.”&lt;/p&gt;

&lt;p&gt;The context ceiling just got a lot higher.&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>claudecode</category>
      <category>specdrivendevelopmen</category>
      <category>codex</category>
    </item>
    <item>
      <title>This Is the Way: Delete the Code</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Tue, 10 Feb 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/this-is-the-way-delete-the-code-2n8m</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/this-is-the-way-delete-the-code-2n8m</guid>
      <description>&lt;p&gt;&lt;em&gt;How I learned to do AI Katas and make disposable code helped me recover from burnout&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Burnout is real, and it takes time to work its way out.&lt;/p&gt;

&lt;p&gt;I spent the last couple of months trying to work up the will to tackle game projects again. Every attempt fizzled. After a 3+ month slog on a project that &lt;a href="https://dev.to/peter_vanonselen_e86eab6/how-many-times-do-you-have-to-build-too-much-to-learn-scope-creep-238g"&gt;refused to reach an end state&lt;/a&gt;. I had nothing left.&lt;/p&gt;

&lt;p&gt;So instead of committing to another massive project, I started playing.&lt;/p&gt;

&lt;p&gt;I came across the Ralph Wingum loop (&lt;a href="https://www.youtube.com/watch?v=RpvQH0r0ecM" rel="noopener noreferrer"&gt;30-min video if you’re curious&lt;/a&gt;) and decided to experiment. The premise is simple: use two Claude skills and a bash script to let an AI go full agent mode. The first skill, &lt;code&gt;/prd&lt;/code&gt;, takes a spec and generates user stories with verifiable acceptance criteria. The second, &lt;code&gt;/ralph&lt;/code&gt;, converts that PRD into JSON. Then you loop over the JSON until done. This is basic agentic coding, but AI-agnostic and surprisingly effective.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.petervanonselen.com%2Fassets%2Fagentic-play%2Fimage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.petervanonselen.com%2Fassets%2Fagentic-play%2Fimage.png" alt="the wiggam loop" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I needed a project to test this on, so I picked &lt;a href="https://boardgamegeek.com/boardgame/163474/v-sabotage" rel="noopener noreferrer"&gt;V-Sabotage&lt;/a&gt;. It’s a board game I enjoy but rarely get to play (toddler life), and more importantly, it’s simple enough to define a clear MVP: rooms, a player, guards, sneaking mechanics, a win condition. I’d learned my lesson about scope.&lt;/p&gt;

&lt;p&gt;The real experiment wasn’t building the game. That was just the head fake. It actually was figuring out how to break down the work. How big should each PRD be? Do you treat each milestone as its own PRD? Do you throw the whole spec at it and see what happens?&lt;/p&gt;

&lt;p&gt;I had to find out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First run:&lt;/strong&gt; I threw a PRD at the skills, ralphed it, and looped on a fresh repo. What came out was very familiar from the last time I was building a game in Godot with AI. Bascially something that worked, but buggy, clunky, no tests, poor signal architecture, tightly coupled code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second run:&lt;/strong&gt; Same PRD, same loop, but this time I initialised the repo with a CLAUDE.md file first. Just basics: test-drive the code, use Godot 4.x best practices, that sort of thing.&lt;/p&gt;

&lt;p&gt;The difference was dramatic. The AI wrote its own test runner. It test-drove everything, achieved high coverage, produced cleaner interfaces, used signals properly, and kept things decoupled. Twenty minutes of compute, and the output was genuinely good. Honestly the thing that blew my mind on this was &lt;strong&gt;it wrote it’s own TEST RUNNER!?!?&lt;/strong&gt;. Are you kidding me?&lt;/p&gt;

&lt;p&gt;So … key lesson: agent files matter. A lot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third run:&lt;/strong&gt; I embedded full milestones into the PRDs—a dozen user stories each, multiple acceptance criteria. The loop churned through it and produced a testable MVP in surprisingly little time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fift8zivoya2r0l2e8454.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fift8zivoya2r0l2e8454.png" alt="stealth game" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fourth run:&lt;/strong&gt; I got distracted by an app idea. Spent a couple of hours refining it with AI, generated a chunky PRD, threw the whole thing at the &lt;code&gt;/prd&lt;/code&gt; skill. It produced 40 stories. I looped it. An hour later, with 5% of my usage allowance remaining, I had a working prototype.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnk9biprbp8sehj2kxvp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnk9biprbp8sehj2kxvp.png" alt="random app" width="800" height="1124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It didn’t do exactly what I wanted. But it did most of what I’d asked. This was surprisingly more than enough to immediately change my thinking about what I actually needed in a meaningful way.&lt;/p&gt;

&lt;p&gt;And here’s the thing that made all of this feel like play instead of work: &lt;strong&gt;I deleted the code.&lt;/strong&gt;. I went full &lt;a href="https://www.coderetreat.org/" rel="noopener noreferrer"&gt;code retreat conways game of life&lt;/a&gt; delete the code.&lt;/p&gt;

&lt;p&gt;Multiple times. Deliberately. The output I was chasing wasn’t a codebase. It was understanding. How big can a PRD get before the loop breaks? (Bigger than I expected.) How much do agent files matter? (More than I expected.) What’s the minimum setup to get something useful? (Less than I expected.)&lt;/p&gt;

&lt;p&gt;Disposable code meant low stakes. Low stakes meant I could experiment freely. And experimenting freely, it turns out, is how I recover from burnout.&lt;/p&gt;

&lt;p&gt;This play has fundamentally changed how I work at The Economist. But that’s a story for next time.&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>claudecode</category>
      <category>specdrivendevelopmen</category>
      <category>codex</category>
    </item>
    <item>
      <title>Why You Shouldn’t Speedrun a Production Refactor</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Fri, 12 Dec 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/why-you-shouldnt-speedrun-a-production-refactor-4l8h</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/why-you-shouldnt-speedrun-a-production-refactor-4l8h</guid>
      <description>&lt;p&gt;&lt;em&gt;Learning the hard way that AI makes discipline more important, not less…&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;This week has been a mess. I’ve been ill since last Thursday with a cough that’s been both productive and dizzying, which in a rare moment of clarity made me realize that maybe doing personal dev in the evenings is… not ideal. So no game dev tales this week.&lt;/p&gt;

&lt;p&gt;Instead, I want to talk about how I nearly torpedoed a production refactor at The Economist a month ago by forgetting the most important lesson I’ve been learning over the past few months: &lt;strong&gt;AI makes discipline more important, not less.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The spectacular failure
&lt;/h2&gt;

&lt;p&gt;I’m currently on the e-comm-funnel team working on the checkout pipeline. One of my first projects has been tackling Commerce Services. This is a Go monolith (a language I’d never used before recently) that started as a POC and got productionized. Naturally, it’s a beautiful mess with conflicting APIs doing all sorts of non-cohesive domain things.&lt;/p&gt;

&lt;p&gt;My goal: break it into microservices.&lt;/p&gt;

&lt;p&gt;So naturally I did what I’ve been practicing with Horizons Edge and started with a spec. I had a very long conversation with Codex, analyzed the repo structure, identified the domains, mapped dependencies. From this chat we produced a solid 10 page high-level plan.&lt;/p&gt;

&lt;p&gt;And the first step of that plan was &lt;em&gt;Phase 1: extract common code into a shared library&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And somewhat predictably, here’s where I got clever.&lt;/p&gt;

&lt;p&gt;I thought: “I’ve got a detailed spec. Codex knows Go. Let’s just… do the whole thing! Whats the worst that could happen?”&lt;/p&gt;

&lt;p&gt;So I did. One massive refactor. Codex happily obliged.&lt;/p&gt;

&lt;p&gt;Then I looked at the pull request: &lt;strong&gt;200 files changed in the monolith. 80 files in the new library.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxir1jgj1e4jvypc7gjpu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxir1jgj1e4jvypc7gjpu.png" alt="this is fine, right?" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And I just stared at it, completely overwhelmed by the obvious question: &lt;em&gt;How the hell am I going to verify this actually works?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There was no way I could meaningfully review 280 files of changes. No way I could ask another engineer to do it. No way to be confident this wouldn’t break something subtle in production. I’d just created an unshippable monster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting over, properly this time
&lt;/h2&gt;

&lt;p&gt;I scrapped the entire thing and started again with an “I need this to be incremental” mindset.&lt;/p&gt;

&lt;p&gt;Not just because I wanted to be able to review it, though that’s critical, but because I genuinely believe small releases into production are the right way to work. It should have been my default starting point. Instead, I’m still learning just how disciplined I need to be when working with AI tooling.&lt;/p&gt;

&lt;p&gt;The new approach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt; , I wrote a much more detailed spec for Phase 1 that lived in the new repo. Not just “extract shared library” but an 8-step plan where each step could go to production independently. Start with the absolute minimum: just one joint service with no dependencies. This would validate the CI/CD pipeline, the integration points, everything, with the smallest possible change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then&lt;/strong&gt; , one step at a time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extracted and deploy leaf utilities (logging, validation, middleware)&lt;/li&gt;
&lt;li&gt;Migrated HTTP routing abstractions&lt;/li&gt;
&lt;li&gt;Moved observability and AWS helpers&lt;/li&gt;
&lt;li&gt;Extracted infrastructure components like health checks&lt;/li&gt;
&lt;li&gt;Finally, the component registry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At each step: tested, improved coverage, deployed to production, monitored. The existing systems kept running exactly as before.&lt;/p&gt;

&lt;p&gt;I followed the same hyper-methodical approach I’ve been using with the game project. Focusing on small scoped MVP slices and incremental delivery. For the actual development, I loaded Codex into a workspace with both repos and had it follow the spec file for each migration. Then validated with Claude in GitHub Copilot, extensive personal review, and eventually team review before each production deployment.&lt;/p&gt;

&lt;p&gt;The result: A refactor of a core system touching ~200 files, in a programming language I’m just learning, in a domain I’d just joined, completed over a couple of weeks with zero downtime. No one on the team was blocked or impacted. It just happened quietly in the background.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’m taking away
&lt;/h2&gt;

&lt;p&gt;Two things keep reinforcing themselves across contexts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt; : AI amplifies your need for discipline. The easier it becomes to generate large amounts of code, the more critical it is to think carefully about scope, verification, and deployment strategy. One-shotting 280 files feels productive in the moment. It’s not. It’s just creating an unshippable mess you’ll have to undo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second&lt;/strong&gt; : The “what’s the smallest increment that adds value?” mindset pays off everywhere. It saved Horizons Edge when I was drowning in scope creep. It made this refactor safe and reviewable. It’s not just a nice-to-have for side projects … it’s how you de-risk production changes in unfamiliar territory.&lt;/p&gt;

&lt;p&gt;Next up is breaking out actual domains into microservices, starting with Identity &amp;amp; User. But that’s a plan for next year, when I’m hopefully no longer coughing my lungs out.&lt;/p&gt;

</description>
      <category>godot</category>
      <category>vibecoding</category>
      <category>claudecode</category>
      <category>specdrivendevelopmen</category>
    </item>
    <item>
      <title>Finally… A Wild MVP Appears</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Thu, 04 Dec 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/finally-a-wild-mvp-appears-39km</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/finally-a-wild-mvp-appears-39km</guid>
      <description>&lt;p&gt;&lt;em&gt;Three Months to MVP: What I Learned Building a Tactical Card Game with AI…&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcit2izofzxlqc2b105fo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcit2izofzxlqc2b105fo.png" alt="banner" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s been three months since I started trying to make Horizon’s Edge, a tactical turn-based wargame in the sky. And honestly, I’m completely stunned that I even have something that actually … kinda … works.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Vibe to Spec
&lt;/h2&gt;

&lt;p&gt;When I started this project, I was pure vibe coding. But somewhere in the middle, when I was trying to refactor the UI from a classic RTS/turn-based strategy with a mass of buttons to something entirely driven by card play, vibe coding hit a wall. I couldn’t get AI tooling to cooperate with my loose intuitions. That’s when I started working with specs and it changed my life…. metaphorical life …. but life!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwstdtbgh6w3e92bpuue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwstdtbgh6w3e92bpuue.png" alt="card driven" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Writing a clear specification before diving head first into a vibe changed everything. Suddenly the AI had guardrails. It stopped looping in circles. If you want to go deeper on this, I wrote about starting to figure out specs in &lt;a href="https://claude.ai/2025/10/03/chaos-cards-and-claude-copy/" rel="noopener noreferrer"&gt;Chaos, Cards, and Claude&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Months of Education
&lt;/h2&gt;

&lt;p&gt;What I’ve learned so far is this: it’s entirely possible to make working software with AI tools. You can keep momentum even when you’re completely out of energy or time. But the most important thing … the thing that actually matters … is that you have to always verify what the AI outputs. Automated unit tests are your best friend here. A Quality Engineers mindset and thinking about edge cases is fundamental.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk85lytdb7ykaglfeu50f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk85lytdb7ykaglfeu50f.gif" alt="waveform generation" width="560" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve done major refactors. I’ve rethought how the game works multiple times. I added procedural generation because it was fun. I figured out how to make the game work with just card play mechanics that… mostly work (much to my surprise). Some refactors were vibe-coded disasters; others were spec-driven and clean. But every single one taught me something about how to work with AI as a tool rather than a replacement.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MVP: What It Took
&lt;/h2&gt;

&lt;p&gt;Two days ago I finished the final major system needed to validate the MVP: the victory system. Islands needed to change ownership. Every existing system needed to integrate with that. Core island nodes needed to be targetable from creatures, spells, and abilities. Getting the targeting code to work meant hitting more touch points than I anticipated. A lot of different abilities needed specific ways to target islands, not just creatures. It was more entertaining than expected, but I had a spec, and that spec kept me honest.&lt;/p&gt;

&lt;p&gt;I now have two thematic decks that are actually unique. 10 creatures. Infrastructure cards that terraform and change the world. A spell that destroys the world. Card play mechanics that mostly work. A whole horde of nuanced and detailed rules about damage and combat that work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prototype done. Well, mostly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The mechanics are all there. What’s left is UI feedback. Cards need to show their play cost clearly, what they do when discarded, what abilities they have before you play them. I know all this because I’ve spent three months building it. Others won’t. So I’m going to tackle those UI gaps this week, then put this in front of a few people to get real feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now It’s Your Turn
&lt;/h2&gt;

&lt;p&gt;I’ve spent the past five months working on this. It started with a Magic the Gathering Pauper Jumpstart cube that just wouldn’t get out of my head, went running headlong into a board game prototype that was way too complicated and barrelled straight into this game. I’ve learned a ridiculous amount. &lt;strong&gt;But here’s what actually matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is possible to make working software with AI. You can make some amazing things with these tools. You can learn as you go. You can ship those crazy ideas you never thought you could.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So here’s what I want:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I want &lt;em&gt;you&lt;/em&gt; go out and make your own mistakes. Build something weird. Use AI as a tool, verify everything it does, and then make something great. Make art. Because making art, well, that’s the most human thing we can do.&lt;/p&gt;

&lt;p&gt;Tell me what you build. I want to hear about it.&lt;/p&gt;

&lt;p&gt;Till then, keep learning.&lt;/p&gt;

</description>
      <category>godot</category>
      <category>vibecoding</category>
      <category>claudecode</category>
      <category>specdrivendevelopmen</category>
    </item>
    <item>
      <title>The Long Road to MVP</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Thu, 27 Nov 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/the-long-road-to-mvp-2nao</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/the-long-road-to-mvp-2nao</guid>
      <description>&lt;p&gt;&lt;em&gt;How I learned to stop overthinking and ship the damn thing…&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyf41lclz4u6quhxhqpv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyf41lclz4u6quhxhqpv2.png" alt="banner" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/peter_vanonselen_e86eab6/how-many-times-do-you-have-to-build-too-much-to-learn-scope-creep-238g"&gt;Last week I had a sudden but inevitable realisation&lt;/a&gt;. Basically my MVP was completely not an MVP but rather a bloated over-built system that I should have been moving to release sooner. Which in hindsight I should have realised… 4 weeks ago. Lesson learned.&lt;/p&gt;

&lt;p&gt;So, this week I started with yet another plan where I detailed out a new spec that broke down the exact things I needed to do. And then… I did just that! Everything else is deferred.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Broad plan for MVP:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 Spell: Meteor - DONE&lt;/li&gt;
&lt;li&gt;1 Victory condition: own all the islands - IN PROGRESS&lt;/li&gt;
&lt;li&gt;2 Unique Decks - TODO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The spell was easy. Just another ability, and make it bigger, cost more and have an animation that then removes a massive amount of real estate. Big, flashy, simple.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiak0p3r348ov9clb1og1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiak0p3r348ov9clb1og1.gif" alt="meteor" width="720" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The victory condition, however, has turned into a far more crunchy problem. Turns out wiring up ownership, health tracking, and win conditions across multiple systems was messier than I thought. I’ve built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;game over&lt;/strong&gt; screen to start a new game&lt;/li&gt;
&lt;li&gt;Health on the core island node&lt;/li&gt;
&lt;li&gt;A UI display to see that health&lt;/li&gt;
&lt;li&gt;A manager to track who owns the islands and a way to change ownership&lt;/li&gt;
&lt;li&gt;A victory condition that checks each round if someone’s actually won&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Almost there! The missing piece is creatures targeting the core island and dealing damage to it. Once I wire up that damage pathway, the whole system clicks. That’s what I’m grinding through at the moment.&lt;/p&gt;

&lt;p&gt;All that will be left is two decks. Which should be as simple as updating two config files, and I’ll have a playable MVP. Finally.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1driuusf043q6efx3oo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1driuusf043q6efx3oo.gif" alt="light" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>godot</category>
      <category>vibecoding</category>
      <category>claudecode</category>
      <category>specdrivendevelopmen</category>
    </item>
    <item>
      <title>How Many Times Do You Have to Build Too Much to Learn Scope Creep?</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Thu, 20 Nov 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/how-many-times-do-you-have-to-build-too-much-to-learn-scope-creep-238g</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/how-many-times-do-you-have-to-build-too-much-to-learn-scope-creep-238g</guid>
      <description>&lt;p&gt;&lt;em&gt;Scope Creep Keeps Teaching Me…&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fey7nbj4r7x5f3cp8rds2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fey7nbj4r7x5f3cp8rds2.png" alt="banner" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Scope Creep Keeps Teaching Me
&lt;/h1&gt;

&lt;p&gt;Have you ever had one of those weeks where you suddenly have to be traveling a lot and don’t really have any time for personal projects? This has been my week. I still managed to get two creatures and six abilities created.&lt;/p&gt;

&lt;p&gt;The Flux Chaos controls the board by moving creatures into and out of position, swapping them from behind enemy lines or randomly teleporting them somewhere (maybe even off into the void). The Flux Storm does massive area damage while locking down the area preventing anyone from teleporting in and out. Watching these creatures interact with the existing systems is delightful. The abilities are beginning to feel like they synergize and interact together nicely.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxuqzgn9yywyzwaa5k76b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxuqzgn9yywyzwaa5k76b.png" alt="chaos and storm" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve been on a mission to prototype this strange game idea for a while now. I started the repo on September 4th. Three months later, I’m watching a prototype that’s actually starting to feel like a game with interesting systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  But here’s what I should have learnt sooner: I didn’t cut far enough.
&lt;/h2&gt;

&lt;p&gt;When I started, I aggressively removed things. All 8 envisioned factions. The single-player campaign, stories, and lore. AI players. Multiplayer. Different form factors like mobile. Complex models and animations. I thought I’d solved the scoping problem. Oh how innocent I was.&lt;/p&gt;

&lt;p&gt;I then built ten creatures with twenty-nine abilities. I added procedural island generation and dynamic road construction. I went down tangents and rabbit holes as I iterated from RTS-style UI to pure card-driven gameplay.&lt;/p&gt;

&lt;p&gt;Looking at that list now, that should have been a warning sign. And it gets worse: my remaining feature list for MVP includes five more buildings, five more spells, multiple win conditions, fog of war, proper turn behavior, UI polish.&lt;/p&gt;

&lt;p&gt;It’s only now that I am looking at my remaining feature list (I wrote up the list for this very blog post), that I realize the entirely obvious thing. I am &lt;em&gt;still&lt;/em&gt; overscoping. Scope creep doesn’t stop after one round of cuts. It’s persistent. Even when you’re actively trying to think in MVP terms, there’s a pull to add one more building, one more spell, one more system. Each one feels necessary. But they compound.&lt;/p&gt;

&lt;p&gt;I should have picked this up sooner: that grinding feeling I’ve been having with the creatures and abilities. It has felt like motivation leeching away in the never ending drudgery. It was a clear warning sign I was off the path.&lt;/p&gt;

&lt;p&gt;So here’s my actual MVP: one spell (meteor), Fog of War, one win condition, UI, and two decks. That’s it. Just the core systems missing, playable, shippable. This is what I should have built from the start, the smallest thing that proves the concept works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgypwfqi1py8x2q6tcby9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgypwfqi1py8x2q6tcby9.webp" alt="simple" width="679" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The lesson keeps teaching itself
&lt;/h2&gt;

&lt;p&gt;I keep learning the same lesson over and over. I thought I’d solved scope creep when I cut factions and campaigns. Three months later, with ten creatures and twenty-nine abilities built, I realized I’d just learned the lesson at a different scale. Every time I ship something, I understand a little better what actually mattered. And every time, I realize I could have cut further.&lt;/p&gt;

&lt;p&gt;The game is starting to have shape because I’ve been building and learning. But I’m also learning, again, that shipping something small and real beats shipping something comprehensive and theoretical. Time to cut deeper. This time, I’m shipping the prototype before I convince myself I need more.&lt;/p&gt;

</description>
      <category>godot</category>
      <category>vibecoding</category>
      <category>claudecode</category>
      <category>specdrivendevelopmen</category>
    </item>
    <item>
      <title>How to Get Things Done When You Have Nothing but Process</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Thu, 13 Nov 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/how-to-get-things-done-when-you-have-nothing-but-process-20ol</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/how-to-get-things-done-when-you-have-nothing-but-process-20ol</guid>
      <description>&lt;p&gt;&lt;em&gt;The tale of how a good System can carry you through the dark times…&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1d223rwcigwu10z8bgx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1d223rwcigwu10z8bgx.png" alt="banner" width="800" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week I had zero motivation. Motivation tank completely empty.&lt;/p&gt;

&lt;p&gt;My goal was 4 creatures and all of the remaining abilities. I only manage to build 2 creatures and 7 abilities instead.&lt;/p&gt;

&lt;p&gt;That happening was astonishing to me.&lt;/p&gt;

&lt;p&gt;But it did. And the reason isn’t hard work or willpower, it’s process. The structure on how to work with AI that I follow is robust enough to produce good work even when I have nothing left. That’s the real story.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the structure holds up
&lt;/h2&gt;

&lt;p&gt;My process is straightforward: compact the conversation, use the spec to guide the next iteration, verify the implementation, have the AI explain what it did, then manually test each ability. Rinse and repeat.&lt;/p&gt;

&lt;p&gt;The spec-driven approach kept context alive, for me &lt;em&gt;and&lt;/em&gt; the AI. While my motivation was completely drained, the AI kept building. I basically did the bare minimum each day before switching to Marvel Spider-Man, but the structure meant I never lost the thread. I was running on &lt;a href="https://www.youtube.com/shorts/mVQ1bzd816I" rel="noopener noreferrer"&gt;Seinfeld method&lt;/a&gt; momentum: just keep the chain unbroken.&lt;/p&gt;

&lt;p&gt;But here’s the critical bit: &lt;strong&gt;verify everything the AI makes&lt;/strong&gt;. The AI will confidently insist “Everything works perfectly!” and update your docs without being asked. Then you test it. Nothing works. You point it out and it turns out half the feature wasn’t there to start with. Point it out again, and more unfinished work is found. The AI is capable and also will miss the obvious. Trust but verify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro tip&lt;/strong&gt; : never ever let the AI update the docs without being directly asked to.&lt;/p&gt;

&lt;p&gt;This verification habit isn’t just bug-catching. It is the key habit that keeps the process from collapsing. Without it, you’re just building on sand. With it, even a low-energy week produces solid work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where designs actually get good
&lt;/h2&gt;

&lt;p&gt;The most valuable phase in my workflow is when the AI explains what it just built. That’s where I stop and think: does this ability actually do what I want? Should it shift? Should it do something different?&lt;/p&gt;

&lt;p&gt;That’s where the magic happens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7mklyoc6nlb5bogf2em.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7mklyoc6nlb5bogf2em.png" alt="tank" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Biomass Tank’s parasitic bond is a perfect example. It started as a triggered ability, shifted into an activated passive that heals the Tank whenever &lt;em&gt;any&lt;/em&gt; nearby enemy creature takes damage. That single design decision cascaded: upkeep suddenly mattered. Rounds had weight. Generator buildings became far more valuable, and vulnerable. The creature went from decent to a potential powerhouse with two different healing methods and the ability to stay safe at range.&lt;/p&gt;

&lt;p&gt;The design got better not because I worked harder on it, but because I paused to think about what it &lt;em&gt;was&lt;/em&gt; and what it &lt;em&gt;could be&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffpnd57ooir3twiaub60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffpnd57ooir3twiaub60.png" alt="defender" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same with the Voltage Defender. Its pull mechanic started simple—nudging creatures around the battlefield. But when I stopped to think about it, it shifted: what if it could move creatures &lt;em&gt;off islands entirely&lt;/em&gt;? Suddenly it’s a broad control tool, shutting down buildings and repositioning the entire battlefield. That cascaded too—every ability needed rework. The EMP got bigger, affected every building including the player’s, made positioning critical.&lt;/p&gt;

&lt;p&gt;This reflection loop, building something, stopping to think about it and then nudging the design. It keeps creating moments where the game gets better. It’s where iteration actually matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real lesson
&lt;/h2&gt;

&lt;p&gt;Turns out the structure matters more than the fuel. Low-energy weeks aren’t failures. They’re tests of process.&lt;/p&gt;

&lt;p&gt;When you have nothing left, you find out what actually works. This week proved that good structure, spec-driven development, verification habits, and the discipline to reflect, can carry you through. The creatures got better not because I pushed harder, but because the process was solid enough to ship good work anyway.&lt;/p&gt;

&lt;p&gt;I might not have had the energy. But the system did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next week
&lt;/h2&gt;

&lt;p&gt;Fingers crossed, I will hopefully be finished the creature cards and start working on spells like Meteor and Lightning and getting some more buildings working correctly.&lt;/p&gt;

</description>
      <category>godot</category>
      <category>vibecoding</category>
      <category>claudecode</category>
      <category>specdriven</category>
    </item>
    <item>
      <title>The Beautiful Boring: How I Refactored a Game Without Breaking it</title>
      <dc:creator>Peter van Onselen</dc:creator>
      <pubDate>Thu, 06 Nov 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/peter_vanonselen_e86eab6/the-beautiful-boring-how-i-refactored-a-game-without-breaking-it-2p5p</link>
      <guid>https://dev.to/peter_vanonselen_e86eab6/the-beautiful-boring-how-i-refactored-a-game-without-breaking-it-2p5p</guid>
      <description>&lt;p&gt;&lt;em&gt;Can an AI Do a Boring Refactor? A Case Study in Systematic Code Cleanup&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fselqipamnuftwuwkk18g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fselqipamnuftwuwkk18g.png" alt="banner" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week, my carefully-laid plans for rapid progress on &lt;strong&gt;Horizons Edge&lt;/strong&gt; , a tactical wargame with card-driven combat on floating islands, collided headfirst with 2,255 lines of code and 94 functions living in a single file. Whoops. Just what I always wanted. I’d let a god class slowly brew and percolate while I focused on shipping features. Now it was time to pay the inevitable technical debt.&lt;/p&gt;

&lt;p&gt;The wonderful file in question: &lt;code&gt;game_manager.gd&lt;/code&gt;. It was managing twelve distinct functional areas: turn management, combat, creatures, cards, abilities, territory, players, and more. The result was tight coupling and maintenance friction of epic proportions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Question that drove me
&lt;/h2&gt;

&lt;p&gt;I’ve spent the last month learning how to work productively with AI on complex coding tasks. And I had a nagging question: &lt;strong&gt;Can an AI do a massive refactor productively? Can you have a boring refactor—a by-the-numbers, tick-the-boxes, super easy, chill refactor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This wasn’t just idle curiosity. When I last &lt;a href="https://www.petervanonselen.com/2025/09/29/the-grand-refactor/" rel="noopener noreferrer"&gt;attempted a refactor of similar scope, it was an spectacular disaster&lt;/a&gt;. I spent two evenings fighting with Claude about types, going in circles while the AI and I kept insisting the other was wrong. The game broke for days. It was a hair-pulling nightmare that never ended. It was painful, demoralizing, and left me deeply skeptical about whether AI could handle large-scale refactoring productively. That experience shaped everything about how I approached this week.&lt;/p&gt;

&lt;p&gt;But this time felt different. &lt;a href="https://www.petervanonselen.com/2025/10/30/exert-of-what-i-learnt/" rel="noopener noreferrer"&gt;I had a plan&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcetjihokaxiqyeifbz0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcetjihokaxiqyeifbz0k.png" alt="a plan" width="545" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting the Constraints
&lt;/h2&gt;

&lt;p&gt;Before diving in, I wanted to be intentional. I asked Claude to analyze the file and create a refactoring plan, but with strict requirements:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functional Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maintain existing behavior. No new code, no feature creep—same behavior, different structure.&lt;/li&gt;
&lt;li&gt;All key systems had to keep working: card play, creature combat, energy systems, turn management, terrain creation and destruction. Everything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Technical Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Files should be less than 400 lines each&lt;/li&gt;
&lt;li&gt;Absolutely no circular dependencies (this still haunts my nightmares)&lt;/li&gt;
&lt;li&gt;Follow good Godot practices using signal-based architecture and node-based composition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Methodology:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything had to be incremental. No big bang refactors. Incremental changes mean incremental testing, which means catching bugs early.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude produced a 1,091-line planning document comprising 11 phases, complete with a testing strategy, regression testing plan, and a high-level architecture with 8 new manager classes. It was exactly what I needed: a detailed roadmap to follow rather than a free-form creative challenge.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Method That Worked
&lt;/h2&gt;

&lt;p&gt;Here’s the systematic approach I followed for every phase:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clean context&lt;/strong&gt; : Open a new terminal window with a fresh Claude context (no conversation history creep)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement one phase&lt;/strong&gt; : Ask Claude to implement just that single phase from the planning document&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify no regressions&lt;/strong&gt; : Get Claude to check to verify its work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a manual test plan&lt;/strong&gt; : Have Claude outline a manual testing plan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hand test and fix&lt;/strong&gt; : Switch back to vibe coding; find bugs, fix them one at a time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit with clarity&lt;/strong&gt; : Once working, commit to the branch with a descriptive message&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This rhythm was key. It prevented the cognitive overload of trying to refactor everything at once while still making steady progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqq60diwzmmyks3z1cwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqq60diwzmmyks3z1cwc.png" alt="commit history" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I started Friday evening and finished Tuesday evening. Seven hours total—an hour Friday night, four hours scattered across the weekend, another hour or two on Monday and Tuesday combined.&lt;/p&gt;

&lt;p&gt;And here’s what shocked me: &lt;strong&gt;the game never broke&lt;/strong&gt;. Not once. This was the easiest refactor of such a complicated system I’ve done in my career.&lt;/p&gt;

&lt;p&gt;The difference was night and day compared to last month. That first refactor had been a hair-pulling nightmare. The game was down for days, I was fighting with the AI in circles, nothing felt under control. This time? The game was working the entire time. Every phase landed in manageable doses. I could test incrementally. I could fix bugs before they cascaded into system-wide failures.&lt;/p&gt;

&lt;p&gt;It’s a quintessential example of risk mitigation in action. Small, verifiable steps beat big, catastrophic swings every time.&lt;/p&gt;

&lt;p&gt;Unlike that previous disaster, this one was systematic. Methodical. Boring, even. It felt like just a matter of following good habits and executing. No dramatic debugging sessions. No circular reasoning about types. No late-night frustration.&lt;/p&gt;

&lt;p&gt;There was something almost boring about how well it worked. And that was the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Taught Me
&lt;/h2&gt;

&lt;p&gt;The breakthrough wasn’t a better AI. It was a better process. By being intentional about constraints, breaking work into small phases, maintaining a testing regimen, and keeping context clean, I transformed a refactoring task from a high-risk, high-stress nightmare into a predictable, manageable project.&lt;/p&gt;

&lt;p&gt;That first refactor failed because I was vibe-coding with the AI. It was reactive, unfocused, trying to solve the whole problem at once. This one succeeded because I treated it like a spec-driven project with a plan, clear objectives, and systematic execution.&lt;/p&gt;

&lt;p&gt;The lesson: AI isn’t magic. It’s a tool. And like any tool, it works best when you know exactly what you’re trying to build and you approach it methodically.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;Now I can finally get back to what I actually want to be doing: making &lt;strong&gt;Horizons Edge&lt;/strong&gt; a better game.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faumbt0bwgn2qmprgwhxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faumbt0bwgn2qmprgwhxg.png" alt="voltage defender" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This coming week: three new creatures with three abilities each. &lt;strong&gt;Voltage Defender&lt;/strong&gt; (exactly what it sounds like), &lt;strong&gt;Biomass Tank&lt;/strong&gt; (a tanky presence), and &lt;strong&gt;Flux Chaos&lt;/strong&gt; (honestly, even I don’t know what this one is yet. That’s kinda the fun of discovery). More abilities. More discipline. More checkboxes to tick.&lt;/p&gt;

&lt;p&gt;Until next time, may your refactors be as boring, and your code as stable, as this one turned out to be.&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>godot</category>
      <category>videogame</category>
      <category>claudecode</category>
    </item>
  </channel>
</rss>
