<?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: Nathan Speich</title>
    <description>The latest articles on DEV Community by Nathan Speich (@nathanspeich).</description>
    <link>https://dev.to/nathanspeich</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4109924%2F5fe9d618-4211-4859-b0a5-c7e4c3c48843.jpg</url>
      <title>DEV Community: Nathan Speich</title>
      <link>https://dev.to/nathanspeich</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nathanspeich"/>
    <language>en</language>
    <item>
      <title>What the AI isn't allowed to do</title>
      <dc:creator>Nathan Speich</dc:creator>
      <pubDate>Thu, 24 Sep 2026 18:25:42 +0000</pubDate>
      <link>https://dev.to/nathanspeich/what-the-ai-isnt-allowed-to-do-163d</link>
      <guid>https://dev.to/nathanspeich/what-the-ai-isnt-allowed-to-do-163d</guid>
      <description>&lt;p&gt;&lt;em&gt;How we build VolunteerPress with AI, the checks every change has to pass, and the bug those checks missed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One evening in July, before version 1.0 shipped, every automated check on VolunteerPress was passing. At the time that was 541 PHP tests, all of them green. Then I did the last thing I do before I accept any change, which is open the site in a browser and use it the way a volunteer would. The calendar showed a shift at one time. The shift list on the same site showed the same shift four hours off.&lt;/p&gt;

&lt;p&gt;Nothing had failed because no test compared those two screens. Tests only confirm what someone thought to ask, and nobody, me included, had asked that. I wrote the bug up, and the next work session began with a search instead of a fix: find every place the plugin shows a date or a time, and check each one. I knew of two. The search found five. Two of the five were emails, the automatic ones a volunteer receives and the ones a coordinator sends to a group. Had that shipped, a volunteer could have been told to show up at the wrong time by the tool that exists to get them there. It was fixed before launch, and all five places now run through one shared piece of code.&lt;/p&gt;

&lt;p&gt;In the first post of this series I wrote that "AI-assisted development" sounds hands-off and isn't, and I promised a full post on how it really works. This is that post, and the story above is the short version: the AI writes the code, and it's still a person's job to find out whether the code is right. I built version one alone, so the stories here are mine. The rules that came out of them are the ones our whole team works under now.&lt;/p&gt;

&lt;p&gt;For my own work I use two AI tools, and they have different jobs. Claude Code works inside the codebase, where it reads the files, writes the change, and runs the tests. The second is an ordinary Claude chat that can't touch the code at all. It helps me plan a change and writes the instructions Claude Code will follow. Later it reviews Claude Code's report on what it did. I sit between them. What gets built and how it should behave are my decisions. The instructions go one way and the report comes back the other through me, and nothing moves forward until I've read it.&lt;/p&gt;

&lt;p&gt;That puts AI on both sides of the work: one tool writes and another reviews. It doesn't put AI in charge. The second chat can flag a problem, but it can't approve a change, and neither tool decides what VolunteerPress does or how it's built. Those decisions, the final read, and the commit are mine.&lt;/p&gt;

&lt;p&gt;Every change starts as a filed issue that says what "done" looks like. For mine, Claude Code gets a fresh session each time, so it works from the project's written rules and the issue in front of it. When it finishes, it writes its report, and four checks run: the PHP coding standards check, the JavaScript lint, the JavaScript unit tests, and the PHP test suite. Right now that's 620 PHP tests and 21 JavaScript tests. The second Claude chat and I go through the report, I test the change in a browser, and only then does it go in.&lt;/p&gt;

&lt;p&gt;Claude Code is not allowed to take that last step. A commit is the moment a change becomes part of the project's permanent history, and Claude Code can't stage files, commit them, or push anything to GitHub. I do that by hand, after the review and the browser check. Committing is where someone says "this is good, and I'm responsible for it," and that someone should be a person whose name is on the project.&lt;/p&gt;

&lt;p&gt;Reviewing a report means reading for what didn't happen. In June, one session came back reporting success, with all of its unit tests passing. The change was almost entirely database queries. A line near the bottom of the report mentioned that the integration tests, the ones that run against a real database, hadn't run in that session, even though they had run in every session before it. The second chat flagged it in its review. Its verdict was that the code was probably fine, and that "probably" isn't good enough for the part of the plugin that reads and writes a nonprofit's volunteer records. I agreed, so the work didn't count as finished until those tests ran. They passed with no changes needed, and the standing instructions now name the exact test script so a session can't skip it.&lt;/p&gt;

&lt;p&gt;The project keeps a plain-text file of standing instructions that an AI tool reads at the start of every session, and it grows each time a session teaches us something. I also ask for evidence. When I had Claude Code compare the website's documentation against what the plugin really does, every problem it flagged had to come with the file and the lines it was based on, and anything it couldn't back up had to be labeled as opinion. It also had to list what it was unsure about separately, because being unsure is a finding too.&lt;/p&gt;

&lt;p&gt;If you run a nonprofit's website, here's what this means for you. VolunteerPress keeps your volunteers' names and contact details in your own WordPress site, and the code that handles them passed all four automated checks before it was released. That lowers the odds of a bug. It doesn't bring them to zero. Version 1.0.1 followed a day after 1.0 with fixes from the first round of feedback. What I can tell you is that the source code ships inside the download for anyone to inspect, and that when you report a problem, we write it up as an issue and it goes through the same process.&lt;/p&gt;

&lt;p&gt;The same rules apply to everyone who contributes. Contributors can use whatever AI tool they like, or none. I've named Claude throughout because it's what I used to build version one, but VolunteerPress isn't tied to any AI company or tool. Every change, whoever makes it, has to start as an issue, pass the four checks, and be reviewed before it merges. If you want to help build it, the way in is at &lt;a href="https://volunteerpress.org/contribute" rel="noopener noreferrer"&gt;volunteerpress.org/contribute&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're building something with AI and you've found a check that catches what the others miss, we'd like to hear about it. And if you run a nonprofit's site on WordPress, download VolunteerPress from &lt;a href="https://volunteerpress.org" rel="noopener noreferrer"&gt;volunteerpress.org&lt;/a&gt; and tell us what happens: &lt;a href="mailto:hello@volunteerpress.org"&gt;hello@volunteerpress.org&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>opensource</category>
      <category>ai</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>The solo phase is over.</title>
      <dc:creator>Nathan Speich</dc:creator>
      <pubDate>Fri, 11 Sep 2026 15:51:30 +0000</pubDate>
      <link>https://dev.to/nathanspeich/the-solo-phase-is-over-34h0</link>
      <guid>https://dev.to/nathanspeich/the-solo-phase-is-over-34h0</guid>
      <description>&lt;p&gt;&lt;em&gt;What it took to onboard the first contributors.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On Saturday, September 5, VolunteerPress stopped being a one-developer project. That was the day of the first contributor onboarding session, held at &lt;a href="https://www.improving.com/locations/columbus/" rel="noopener noreferrer"&gt;Improving&lt;/a&gt; in Columbus during the &lt;a href="https://christians-in-tech.org/" rel="noopener noreferrer"&gt;Christians in Tech Columbus&lt;/a&gt; meetup. The first contributors got their laptops out and started setting up their development environments. The session itself is easy to describe. What's worth writing about is the set of decisions that made it possible, and what watching contributors use them changed.&lt;/p&gt;

&lt;p&gt;VolunteerPress is a WordPress plugin, so to work on it you need WordPress running on your own machine, which means PHP and a MySQL database. To check the code the way the project checks it, you also need Composer and Node. That's five things that have to exist and agree with each other before you can change a single line of code, on whatever laptop you walked in with. The goal was concrete: someone should go from nothing installed to passing the same automated checks the project runs before every change, in one sitting. Every decision below came from that.&lt;/p&gt;

&lt;p&gt;That goal decided the foundation. I chose LocalWP, a free desktop app that runs WordPress sites on your computer and ships its own PHP and MySQL. Docker is the more standard answer, and it's what the WordPress core team uses for its own contributors. LocalWP won for three reasons. Onboarding is faster, because PHP, MySQL, and WordPress arrive together instead of one install at a time. The environment is standardized, because every contributor runs the PHP and MySQL that LocalWP ships, whatever their operating system. And it has a site shell: one click opens a terminal with that site's PHP, database, and WordPress command line already wired up, so everyone starts from an identical place on Windows, macOS, or Linux. It's also a tool WordPress developers already know from client work, and it works well for contributors at every skill level.&lt;/p&gt;

&lt;p&gt;The trade-off is that contributors depend on a desktop app instead of assembling standard tools themselves, and if LocalWP changes something, our setup guide changes with it. For this project, that's worth it.&lt;/p&gt;

&lt;p&gt;That choice shaped the setup guide. It has three sections, one per operating system. Windows, macOS, and Linux each get their own path to installing LocalWP, Composer, and Node, and those three installs are the last point where the operating system matters. On Windows, for example, Composer needs to know where PHP lives, so rather than have people install a second copy, the guide points it at the one LocalWP already downloaded. From the moment you open the site shell, every command in the guide is identical for everyone. I wanted a contributor on Windows and a contributor on a Mac sitting next to each other to be able to look at each other's screens and see the same thing.&lt;/p&gt;

&lt;p&gt;Then there was deciding what "done" means for setup. Loading the site in a browser isn't it. Passing the checks is. Every change to VolunteerPress, including a one-line fix to a documentation file, has to clear four of them: the PHP coding standards check, the JavaScript lint, the JavaScript unit tests, and the PHP test suite. Right now that's 620 PHP tests with 3,720 assertions, and 21 JavaScript tests. The PHP test suite needs a live database and a setup the project only supports on Linux, so the work is split. Everyone runs the first three checks on their own machine, and GitHub runs all four automatically on every proposed change, whatever machine it came from. A contributor on Windows or a Mac never has to get the PHP test suite working locally.&lt;/p&gt;

&lt;p&gt;Running checks for a typo fix sounds excessive, and I understand why. The reason to do it anyway is that the first time a contributor runs those commands, they're not really testing the code. They're testing their environment. If the checks pass, you're set up, and that's the point where the setup guide hands you off to picking up an issue.&lt;/p&gt;

&lt;p&gt;The other decisions were about access and process. Contributors now join a Contributors team in the GitHub organization with triage permission on both repositories, the plugin and the volunteerpress.org site. Every change starts as a filed issue, so there's a record of what's being worked on and why before any code moves. The one exception is an emergency fix, a security issue or a live-site outage, which can go out immediately as long as the issue is filed the same day. The record stays complete either way.&lt;/p&gt;

&lt;p&gt;I also rewrote the issues labeled good first issue. A title and a sentence isn't enough for a first issue. Each one now names the files involved and says what "done" looks like, so a new contributor can pick one up and know when to stop.&lt;/p&gt;

&lt;p&gt;One more rule is about how the code gets written. Last week I said Claude Code wrote the code for version one while I owned the architecture, the requirements, and the testing. That's still how it works, and contributors are welcome to work the same way. The rules that matter now live in the contributing guide and a conventions file, where both a person and an AI coding tool can read them: the four checks, the issues-first workflow, and review before anything merges. There's a small file at the root of the repository that points any of those tools at both documents, whichever one a contributor prefers. An AI-assisted contribution goes through the same four checks and the same review as any other, and the contributor owns the result.&lt;/p&gt;

&lt;p&gt;Very little of the work to open the project up was code. At launch, the plugin already had its tests, its coding standards, and a clean architecture. What it was missing was everything a second developer needs before touching any of that: a way to get a working environment, a definition of when setup is finished, a definition of when an issue is finished, and the project's rules written down somewhere other than my head. Opening VolunteerPress to contributors meant building those things.&lt;/p&gt;

&lt;p&gt;The setup guide that went into that session was a first version, not a final one. Every question a contributor asked that afternoon pointed at an assumption the guide was making without saying so. The steps were all there. What they needed was the clarity that comes from people willing to sit down, try it, and say where it stopped making sense. Those questions produced the version in the repository now, and that's how every part of VolunteerPress moves: it ships, people use it, and it gets better. That's what building in the open, with other people, gives you.&lt;/p&gt;

&lt;p&gt;So here's the change since last week. VolunteerPress is a team now, and it meets in person. For now, onboarding happens at &lt;a href="https://christians-in-tech.org/" rel="noopener noreferrer"&gt;Christians in Tech Columbus&lt;/a&gt; meetups. If you're in Columbus or anywhere nearby and you'd like to build something that nonprofits will actually use, come to one, bring a laptop, and tell me you want in. You don't need to be a WordPress developer, and you don't need to be a regular. Where onboarding happens will change as the group grows beyond the meetup. Online sessions for people who can't make it in person are part of the plan, with no date yet. Any changes will be posted at &lt;a href="https://volunteerpress.org/contribute/" rel="noopener noreferrer"&gt;volunteerpress.org/contribute&lt;/a&gt;. If you'd rather ask a question first, write to &lt;a href="mailto:hello@volunteerpress.org"&gt;hello@volunteerpress.org&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>opensource</category>
      <category>buildinpublic</category>
      <category>community</category>
    </item>
    <item>
      <title>Finding volunteers was easy. Managing signups wasn't.</title>
      <dc:creator>Nathan Speich</dc:creator>
      <pubDate>Fri, 04 Sep 2026 14:55:09 +0000</pubDate>
      <link>https://dev.to/nathanspeich/finding-volunteers-was-easy-managing-signups-wasnt-348e</link>
      <guid>https://dev.to/nathanspeich/finding-volunteers-was-easy-managing-signups-wasnt-348e</guid>
      <description>&lt;p&gt;&lt;em&gt;Why we built VolunteerPress, free volunteer management for WordPress, and how anyone can help build what's next.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Small nonprofits in Columbus, Ohio, the kind that feed and house people, run entirely on volunteers. Through &lt;a href="https://christians-in-tech.org/" rel="noopener noreferrer"&gt;Christians in Tech Columbus&lt;/a&gt;, a meetup I co-founded and organize, I’ve sat with a handful of them, and every one described the same thing. Not one of them had trouble finding volunteers. Interest was never the problem. What they lacked was a way to manage the volunteers they had: to cap a shift, keep track of who was coming, and communicate with everyone without doing all of it by hand.&lt;/p&gt;

&lt;p&gt;Here’s what that looked like. Volunteers found the organization’s website and filled out a contact form. A staff member read each one and replied by hand. There was no way to cap how many people signed up for a day, so too many showed up or too few. Then every name got typed into a database on a separate platform the organization was paying for. None of it was broken. It was just human hours going to work that software should have been doing, and those hours came straight out of the mission.&lt;/p&gt;

&lt;p&gt;A few of us from the meetup started working on it with them. We mapped what they actually needed, tried what already existed, and weighed what it would take to build something new. The free WordPress plugins were too basic or no longer supported. The good tools cost $50 to $300 a month, which is hard for a small nonprofit to justify when that money could go to the people it serves. And the all-in-one nonprofit suites a few of them already paid for do include volunteer scheduling, but every volunteer has to download an app and create an account to use it. The nonprofits wouldn’t ask that of someone who just wants to show up and help. What they wanted was simple to say and hard to find: signups on the site they already have, with limits, no new accounts, and no person in the middle.&lt;/p&gt;

&lt;p&gt;The “site they already have” part decided the platform. Nearly six in ten nonprofits worldwide run their websites on WordPress, according to &lt;a href="https://www.nptechforgood.com/101-best-practices/website-statistics-for-nonprofits/" rel="noopener noreferrer"&gt;Nonprofit Tech for Good’s Global NGO Technology Report&lt;/a&gt;. Building for WordPress meant the fix could land inside something they already own. It also meant the work wouldn’t stop at Columbus. The same manual process is happening at small nonprofits everywhere, and most of them are on WordPress too. Solve it once as a plugin, and every one of them can install it.&lt;/p&gt;

&lt;p&gt;That’s where VolunteerPress came from. I took version one on myself to get something real in front of them. Claude Code wrote the code, and I owned the architecture, the requirements, and the testing. Every change runs through automated tests and WordPress coding-standard checks (PHPUnit, phpcs, and JS lint) before it merges. Right now that’s 620 PHP tests and 21 JS tests. I’ll write a full post on how that workflow really looks. “AI-assisted development” sounds hands-off. It isn’t.&lt;/p&gt;

&lt;p&gt;The most important choice in version one isn’t a feature at all. VolunteerPress doesn’t bring its own look. The signup form, shift list, and calendar inherit whatever the site’s theme already uses, so there’s nothing to style, nothing to configure, and no designer to hire. A volunteer signing up sees the same site they already trust, not a form that looks bolted on. That’s the reason it works on themes none of us have seen.&lt;/p&gt;

&lt;p&gt;Version 1.0 went live on August 22, the same morning I gave the first talk on it at the meetup and ran a live demo that afternoon. 1.0.1 followed a day later with fixes from that first round of feedback, and that’s how it’ll keep going: the roadmap is driven by what the nonprofits we’re working with ask for. Volunteer hours tracking, which they need for grant reporting, is one of the first things coming. It’s free, open source (GPL), and self-hosted: you download it from volunteerpress.org, it updates itself from there like any other plugin, and the source ships in the zip.&lt;/p&gt;

&lt;p&gt;The solo phase is over. VolunteerPress is an open source project with an in-person on-ramp: you come to an onboarding session, get set up on the codebase, pick up an issue, and own it through review. Anyone is welcome, and you don’t have to be part of the meetup to come. The first session is Saturday, September 5, at Improving in Columbus, running alongside the &lt;a href="https://christians-in-tech.org/" rel="noopener noreferrer"&gt;Christians in Tech Columbus&lt;/a&gt; meetup. Future sessions will be listed at volunteerpress.org/contribute.&lt;/p&gt;

&lt;p&gt;I write every Thursday at &lt;a href="https://blog.nathanspeich.com/" rel="noopener noreferrer"&gt;blog.nathanspeich.com&lt;/a&gt;. For now that means building VolunteerPress: what shipped, what broke, and what we learned along the way.&lt;/p&gt;

&lt;p&gt;If you run a nonprofit’s website on WordPress, download it and tell us what happens. Write to &lt;a href="mailto:hello@volunteerpress.org"&gt;hello@volunteerpress.org&lt;/a&gt;. Especially if you’re the one replying to contact form submissions by hand right now.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>opensource</category>
      <category>buildinpublic</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
