<?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: Michael Chambers</title>
    <description>The latest articles on DEV Community by Michael Chambers (@mchambers).</description>
    <link>https://dev.to/mchambers</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%2F33054%2F8df0f618-7437-4130-8821-091fe4daaead.jpg</url>
      <title>DEV Community: Michael Chambers</title>
      <link>https://dev.to/mchambers</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mchambers"/>
    <language>en</language>
    <item>
      <title>WordPress Plugin Cross Post for Dev.to: my solution to abandoned and unmaintained plugins</title>
      <dc:creator>Michael Chambers</dc:creator>
      <pubDate>Tue, 28 Jul 2026 09:58:48 +0000</pubDate>
      <link>https://dev.to/mchambers/wordpress-plugin-cross-post-for-devto-my-solution-to-abandoned-and-unmaintained-plugins-3cac</link>
      <guid>https://dev.to/mchambers/wordpress-plugin-cross-post-for-devto-my-solution-to-abandoned-and-unmaintained-plugins-3cac</guid>
      <description>&lt;p&gt;I’ve released &lt;strong&gt;Cross Post for Dev.to&lt;/strong&gt;, a WordPress plugin that mirrors a post to Dev.to the moment you publish it on your own site. The plugin itself is simple: one hook, one API call, one published mirror. The interesting part of this release isn’t the feature. It’s what had to be true for a zero-dependency plugin to stay trustworthy over time without me babysitting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Most small WordPress plugins rot over time. They’re built against whatever WordPress version happens to be current, they lean on a third-party library or two to save time, and neither the plugin nor the library gets revisited until something breaks. Usually a major WordPress release, sometimes a PHP version bump. At that point the maintainer generally abandons the project and so many of these lesser used plugins become useless for users.&lt;/p&gt;

&lt;p&gt;Cross-Post for Dev.to needed to cross-post reliably from WordPress to Dev.to without letting that happen so easily. No bundled third-party SDKs, no external service sitting between the plugin and the Dev.to API, no dependency that could go unmaintained while the plugin using it kept shipping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why zero-dependency isn’t the whole answer
&lt;/h2&gt;

&lt;p&gt;Removing dependencies fixes one kind of rot but not the other. A plugin with no third-party packages can still quietly break against a new WordPress release; deprecated hooks, changed REST behaviour, PHP version drift. Zero dependencies means less that can fail underneath you; it says nothing about whether the plugin still works today. Those are two different guarantees, and conflating them is how “lightweight” plugins end up just as unmaintained as heavy ones, only with fewer visible warning signs.&lt;/p&gt;

&lt;p&gt;So the actual problem wasn’t “avoid dependencies.” It was “know, continuously and automatically, whether this plugin still works”. Which is a validation problem, not a packaging problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The validation loop
&lt;/h2&gt;

&lt;p&gt;Two layers of the same idea, one local and one continuous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Locally&lt;/strong&gt;, a pre-push hook runs before any commit leaves my machine: PHP linting, PHPCS against the WordPress coding standards, PHPStan for static analysis, then the unit and integration suites. If any of it fails, the push is blocked. This isn’t about catching typos, it’s about making sure a mistake never gets far enough to become someone else’s problem. The cost of finding a broken assumption is lowest the moment it’s introduced; a pre-push hook enforces that you pay it there, not after it is merged and breaking the main branch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In CI&lt;/strong&gt;, GitHub Actions runs the same checks against a matrix of PHP and WordPress versions on every push and on a schedule, independent of whether I’ve touched the code recently. That schedule matters more than it looks. WordPress core changes without waiting for plugin authors to notice, and a plugin that hasn’t been touched in eight months can silently stop being compatible with a WordPress release that shipped in month six. Scheduled CI turns “will this still work when someone installs it next week” from a question I’d have to remember to ask into one the pipeline answers on its own.&lt;/p&gt;

&lt;p&gt;The local hook and the CI pipeline check the same things for a reason: local checks exist to keep bad changes from leaving my machine; CI exists to keep bad &lt;em&gt;environments;&lt;/em&gt; a new WordPress version or a new PHP version, from silently invalidating changes that were fine when they were written. Neither one substitutes for the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this actually enables
&lt;/h2&gt;

&lt;p&gt;The real capability this buys isn’t “fewer bugs,” though that’s a side effect. It’s &lt;strong&gt;new WordPress or PHP versions stop being a maintenance crisis&lt;/strong&gt;. Scheduled CI runs the test suite against a matrix of PHP and WordPress versions automatically. When WordPress 6.8 ships or PHP 8.4 goes stable, the pipeline runs the suite the same day. If it passes, great, the plugin is already known to be compatible. If it fails, I see the failure immediately and can fix it or publish a patch before a user even tries to upgrade.&lt;/p&gt;

&lt;p&gt;That’s continuous validation without continuous attention: a plugin only stays trustworthy when someone is actively confirming it still works, and for most maintainers that someone is a person checking manually, usually late. This pipeline makes it an automated process, checking constantly, against the exact environments users will upgrade into, on a schedule that doesn’t depend on my memory or available time.&lt;/p&gt;

&lt;p&gt;The end goal is pragmatic: new WordPress versions and PHP versions don’t impact this plugin in 99% of cases because the pipeline catches them and pushes a new release confirming that. In the remaining 1% of cases where there is a problem I’m notified about, I manually fix and publish a new release. That happens whether I’ve thought about the plugin that week or not.&lt;/p&gt;

&lt;p&gt;That’s the same shift documentation-driven AI development is built on, and it’s worth naming directly: &lt;a href="http://michaelmchambers.co.uk/ai-development-is-a-documentation-problem-not-a-prompting-problem/" rel="noopener noreferrer"&gt;AI development is a documentation problem, not a prompting problem&lt;/a&gt; makes the case that AI coding tools don’t fail because of weak prompts. They fail because the surrounding context (docs, constraints, expected behaviour) isn’t captured anywhere machine-readable. The plugin’s CI pipeline is that same principle applied to compatibility instead of context: don’t rely on someone remembering to check. Encode the check so it runs whether they remember or not.&lt;/p&gt;

&lt;p&gt;The code and pipeline are open: &lt;a href="https://github.com/MChambers1992/cross-post-devto" rel="noopener noreferrer"&gt;github.com/MChambers1992/cross-post-devto&lt;/a&gt;. The plugin itself is on WordPress.org: &lt;a href="https://wordpress.org/plugins/cross-post-for-dev-to/" rel="noopener noreferrer"&gt;wordpress.org/plugins/cross-post-for-dev-to&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
    </item>
    <item>
      <title>AI Development Is a Documentation Problem, Not a Prompting Problem</title>
      <dc:creator>Michael Chambers</dc:creator>
      <pubDate>Wed, 01 Jul 2026 12:28:31 +0000</pubDate>
      <link>https://dev.to/mchambers/ai-development-is-a-documentation-problem-not-a-prompting-problem-1bkb</link>
      <guid>https://dev.to/mchambers/ai-development-is-a-documentation-problem-not-a-prompting-problem-1bkb</guid>
      <description>&lt;p&gt;Most developers start using AI coding tools the same way. They open a chat, describe what they want, and ask it to write the code. Sometimes it works. More often, it produces something almost there but slightly wrong, and fixing it costs more time than it saved.&lt;/p&gt;

&lt;p&gt;That was my experience too, until I changed how I approached using AI in my work. The difference was not the model. It was the method. I have used this approach with both GitHub Copilot and Claude across professional and personal projects, and it has consistently outperformed ad-hoc prompting. What I eventually realised is that I did not have a prompting problem. I had a context management problem. Once I started treating documentation as a shared memory system between me and the AI rather than project paperwork, I immediately noticed the benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem I Kept Running Into
&lt;/h2&gt;

&lt;p&gt;When I asked an AI tool to build something without proper context, I was asking a capable developer to work from a rough verbal description. It would fill gaps with assumptions. The output reflected those assumptions, not my actual requirements.&lt;/p&gt;

&lt;p&gt;The result was code that compiled, looked reasonable, and missed the point.&lt;/p&gt;

&lt;p&gt;There was a second problem compounding that. AI sessions have limits. Context windows fill up, sessions time out, and picking up mid-project means re-explaining everything the tool no longer has access to. Without structure in place, each new session felt like starting from scratch. The tool would drift, contradict earlier decisions, or hallucinate details about code it could no longer see. The problem was not the tool. It was the lack of shared context.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Software Engineering Already Knew
&lt;/h2&gt;

&lt;p&gt;Looking back, I was rediscovering something software engineers have understood for decades. Requirements matter. Specifications matter. Shared understanding matters.&lt;/p&gt;

&lt;p&gt;Teams that write architecture decision records, do not do it because they enjoy writing documents. They do it because decisions made without a written record get forgotten, misremembered, or invisibly reversed. The same dynamic applies when working with AI tools, except the stakes are compressed into a single session. An AI tool without a specification is in exactly the same position as a developer joining a project on day one with no documentation and no handover. It will do something, but it will do it based on guesswork rather than intent.&lt;/p&gt;

&lt;p&gt;What AI has not replaced is the need for clarity before execution. It has amplified it. A developer working from ambiguous requirements might ask clarifying questions or flag the ambiguity. An AI tool will proceed confidently and produce something wrong. The principle has not changed. The leverage has. A poorly written specification might slow down a developer. The same ambiguity can send an AI system down an entirely different path.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern I Settled On: Plan, Document, Build
&lt;/h2&gt;

&lt;p&gt;Across several projects, I have settled on this consistent three-stage approach. Your mileage may vary, but for me this has improved both output quality and reduce the overall time to produce working code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage one is planning with the AI.&lt;/strong&gt; Before writing a line of code, I use the tool as a thinking partner. I describe the problem, the constraints, what I want to avoid, and what success looks like. This is a conversation, not a prompt. It often takes several exchanges and the plan changes as I think through it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage two is producing the shared memory system.&lt;/strong&gt; Once the plan feels solid, I ask the tool to turn it into a structured implementation guide, something detailed enough that a developer, or a completely fresh AI session, could build the project from scratch without clarification. For a download module, that means defining input sources, retry behaviour, storage location, error handling, and expected output contracts. Every integration point written down, every edge case considered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage three is building from it.&lt;/strong&gt; Individual tasks become smaller and more contained. Instead of “build me a pipeline that does X”, each prompt becomes “implement the download module described in section 3 of this guide.” The output is more accurate because the context is explicit rather than inferred.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Shared Memory System in Practice
&lt;/h2&gt;

&lt;p&gt;AI tools do not retain memory between sessions. Every time you start a new conversation, the tool has no idea what you built yesterday, what architectural decisions were made, or what constraints were agreed. Without the guide, the first part of every session is reconstruction. With it, you hand the tool the document, point to the relevant section, and pick up exactly where you left off.&lt;/p&gt;

&lt;p&gt;The habit that makes this work is marking progress directly in the guide as you go. Completed sections get marked done. Decisions that shifted during implementation get noted inline. The tool is reading facts rather than guessing at them. In practice this has almost entirely eliminated the drift and hallucination problems I used to run into regularly.&lt;/p&gt;

&lt;p&gt;It also removes the anxiety around session limits. Each session has a bounded task drawn from the guide, and progress is captured before moving on. The next session picks up cleanly from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Few Habits That Have Helped
&lt;/h2&gt;

&lt;p&gt;Once the implementation guide exists, the prompts themselves become simpler. These habits evolved through trial and error, but they have held up consistently across both tools I have tested this with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference the guide explicitly at the start of every session.&lt;/strong&gt; Provide the relevant section and state clearly what is being implemented. Relying on conversational continuity reduces output quality. Explicit context restores it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One module at a time.&lt;/strong&gt; Bounded tasks produce reliable, testable code. Unbounded prompts invite shortcuts and inconsistencies. The specification defines the boundary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ask for tests against the specification, not just the implementation.&lt;/strong&gt; When the guide defines correct behaviour, tests can be written against that definition. This catches a different category of bugs than implementation-only testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treat the guide as a living document.&lt;/strong&gt; When something changes during implementation, update it immediately. This is the equivalent of keeping ADRs current when a decision is revisited. Without it, the shared memory drifts from reality and stops being reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  When This Approach Is Overkill
&lt;/h2&gt;

&lt;p&gt;Not every task warrants this. For small scripts, quick one-off automation, or narrow prototypes, the overhead of upfront planning outweighs the benefit. Direct prompting works fine and iteration is low cost.&lt;/p&gt;

&lt;p&gt;The pattern pays off on anything with multiple components, anything spanning more than one session, or anything where consistency between modules matters. The more complex the project, the more the absence of a shared memory system costs in drift, rework, and debugging time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Actually Changes
&lt;/h2&gt;

&lt;p&gt;The reality is that most developers are treating AI tools as a prompting problem when they are actually facing a context management problem. Better prompts produce marginal gains. A shared memory system changes the quality ceiling entirely.&lt;/p&gt;

&lt;p&gt;This becomes clear once you experience the difference. The tool stops drifting. Sessions stop feeling like they are fighting against an invisible limit. Output becomes consistent because the inputs are consistent. The specification does not just guide the AI. It eliminates the conditions that produce unreliable output in the first place.&lt;/p&gt;

&lt;p&gt;AI development is not primarily a prompting problem. It is a documentation problem. Treat it accordingly, and the tools available today become significantly more capable than most developers currently experience them to be. That is not a small shift in productivity. For complex projects spanning multiple sessions, it is the difference between a tool that works and one that does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Start
&lt;/h2&gt;

&lt;p&gt;The entry point is low cost. Start a conversation with your AI tool of choice and describe the problem you are solving, not the implementation, the problem. Ask it to produce a structured plan, push back on anything that does not fit, and refine it until it accurately represents what you want to build. Then ask it to turn that plan into a detailed implementation guide that a fresh AI session could execute from scratch.&lt;/p&gt;

&lt;p&gt;That document has been worth more to me than any individual prompt I have written. I have used this pattern with both Copilot and Claude across different project types, and the core approach holds regardless of which tool is being used, because the underlying problem it solves is the same in both cases.&lt;/p&gt;

&lt;p&gt;Improving this one capability, building a shared memory system before building anything else, is one of the highest-leverage changes a developer can make to how they work with AI tools today.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
