<?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: kanfu-panda</title>
    <description>The latest articles on DEV Community by kanfu-panda (@kanfu-panda).</description>
    <link>https://dev.to/kanfu-panda</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%2F3940859%2F45897ada-53a1-4e66-a3ca-356f624df48e.jpeg</url>
      <title>DEV Community: kanfu-panda</title>
      <link>https://dev.to/kanfu-panda</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kanfu-panda"/>
    <language>en</language>
    <item>
      <title>How pdlc-skills Runs Unattended</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Mon, 31 Aug 2026 14:17:05 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/how-pdlc-skills-runs-unattended-3k4a</link>
      <guid>https://dev.to/kanfu-panda/how-pdlc-skills-runs-unattended-3k4a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The last post got the first feature through. The next problem shows up fast: it stops at every stage waiting for your nod, so you're still parked in front of the screen. &lt;strong&gt;Can it go round after round on its own while you do something else?&lt;/strong&gt; It can. But "running on its own" and "asking you at every step" are further apart than they look.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  That run wasn't a loop at all
&lt;/h2&gt;

&lt;p&gt;I've run a full loop on my own machine before, and it went smoothly — 60-odd PRs pushed through in one stretch, and it never once turned around to ask me something. So when I ran it again on a different machine, something felt off almost immediately.&lt;/p&gt;

&lt;p&gt;That time I'd asked the AI to "advance through the stages in a loop" &lt;strong&gt;inside a single session&lt;/strong&gt;. It was moving forward, all right, but it came back to me at every step: is this design OK? Should I keep going? Want me to continue?&lt;/p&gt;

&lt;p&gt;What I said at the time was roughly: &lt;strong&gt;why is your loop different from the one I've been using? A normal loop doesn't turn around and ask me this stuff — it just keeps working until the job is done.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The problem wasn't that it asked. It's that &lt;strong&gt;everything it asked about was already settled&lt;/strong&gt;. The PRD was settled, the design was settled, how the tests would be written was settled — and it still came back for confirmation. That kind of check-in does nothing but tie me to the chair. I can't go do anything else, because I don't know whether the next interruption is three minutes away or thirty.&lt;/p&gt;

&lt;p&gt;On the surface it was looping. In practice I was the one jogging alongside it.&lt;/p&gt;

&lt;p&gt;That's what made it click: &lt;strong&gt;there's exactly one line between a fake loop and a real one — who holds control of the loop.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1c4gbdbz04mrw2kqqxvs.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1c4gbdbz04mrw2kqqxvs.png" alt="Fake loop vs real loop across four points: loop written inside the session or driven by code, whether each round starts on clean context, whether trouble means asking a human or hitting a guardrail, and whether the stop decision reads the model's mood or a file on disk" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It has nothing to do with how smart the model is, and nothing to do with whether the prompt says "please work autonomously, don't interrupt me." If control lives in the model's willingness, the loop is fake. If it lives in code, it's real.&lt;/p&gt;

&lt;h2&gt;
  
  
  One feature: one command is enough
&lt;/h2&gt;

&lt;p&gt;The hard prerequisite first: &lt;strong&gt;PRD and design must be signed off by a human. Nothing enters the loop until the design is final.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The loop speeds up the &lt;code&gt;TDD → implement → review&lt;/code&gt; convergence stretch. It does not speed up figuring out what to build. Whether this feature is worth doing, where its boundaries sit, how it splits — those are judgement calls, and no command can hand you an exit code for them.&lt;/p&gt;

&lt;p&gt;Once that's settled, the rest is one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/pdlc-loop-run F20260825-XXXXXX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It picks up from whatever stage the feature is parked at and drives &lt;code&gt;tdd → implement → review&lt;/code&gt; forward until review passes or it stops on a block. Each stage goes to a brand-new subagent; when that returns, the loop reads the state machine and decides whether to advance, stop, or hand back to you. Four steps by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This assumes the &lt;code&gt;test-commands.yml&lt;/code&gt; from the last post is already in place.&lt;/strong&gt; Stop decisions rest on exit codes from real command runs — no file, no commands to run. Skip that step and everything here spins in place.&lt;/p&gt;

&lt;p&gt;What the command takes off your hands is exactly what I fumbled the first time I tried this by hand: &lt;strong&gt;the decision about whether to go one more round is taken away from the model.&lt;/strong&gt; Three design points hold it up.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc5nvx4wog419ltbkrtl2.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc5nvx4wog419ltbkrtl2.png" alt="One round in three beats: ask what's next (output filtered through a whitelist), do that step (clean context), read the state file to decide whether to stop; the in-plugin runner and an external script keep the same beat" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One: control flow is code, not something in the model's head.&lt;/strong&gt; Each round asks the model two things only — which command comes next, and getting that step done. The answer to the first has to pass a whitelist that accepts five tokens and nothing else; a single extra word of explanation gets filtered out. &lt;strong&gt;Rambling gets the model nowhere, because nothing downstream reads it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two: every stage starts on clean context.&lt;/strong&gt; The previous stage's hesitation, misreadings and self-inflicted detours don't carry over. Everything that has to survive across stages lives in the state file on disk — the one from post 3. &lt;strong&gt;Sessions can die; state doesn't.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three: the stop decision reads a file, not an opinion.&lt;/strong&gt; After each step the loop doesn't ask "do you think that passed?" — it reads &lt;code&gt;last_phase_result.ok&lt;/code&gt;, the on-disk result of actually running the commands. Post 3 covered the two slots in that file; &lt;strong&gt;the stop decision uses only the one that holds real run results&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A dozen features: now you want an external script
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/pdlc-loop-run&lt;/code&gt; runs inside the plugin, which suits one feature's short convergence. You can also write your own bash loop — every round gets a genuinely separate process, so context isolation is stricter and long runs hold up better — but &lt;strong&gt;running one feature point that way isn't worth much on its own&lt;/strong&gt;: it does the same job as &lt;code&gt;/pdlc-loop-run&lt;/code&gt; with a different process boundary.&lt;/p&gt;

&lt;p&gt;The script's real place is one layer out. Post 3 sketched the two-level structure: split the work into N reasonably independent feature points, and have the outer layer start a loop for each, every one in its own worktree. The outer layer starts loops, collects results and queues the next batch — it doesn't push any single feature through its stages. What this post adds is how that outer layer is arranged: &lt;strong&gt;batched by dependency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An earlier project of mine had something like a dozen feature points, and I ran them in three batches: &lt;strong&gt;foundation first, then the ones other work depends on, then everything mutually independent all at once.&lt;/strong&gt; Each batch runs in parallel internally; when a batch finishes I check it, then the next batch starts, until the whole set has converged.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu9gf1mtx4q3sjjsp0pat.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu9gf1mtx4q3sjjsp0pat.png" alt="A dozen feature points in three dependency batches: foundation, then depended-upon features, then mutually independent ones all at once; parallel within a batch, with a human check between batches" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The order can't be flipped. Without the foundation everything after it rests on nothing; until the depended-upon work is done, whatever depends on it just waits. That last batch waits on nobody, so opening it all at once is the cheapest — feature IDs use date-plus-timestamp precisely so parallel runs don't collide.&lt;/p&gt;

&lt;p&gt;To be clear: &lt;strong&gt;this batching layer is mine, not something pdlc provides.&lt;/strong&gt; What pdlc gives you is "how one feature point drives itself to done," plus the &lt;code&gt;/pdlc-relate&lt;/code&gt; dependency graph to see who depends on whom. How to split the batches, and how many go in each, stays a judgement call — and stays outside the loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four guardrails, and I've watched every one of them work
&lt;/h2&gt;

&lt;p&gt;Anyone can write guardrails into a doc. What's worth looking at is whether they've ever actually fired.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpi6s5cxafk1kj0wk8ayb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpi6s5cxafk1kj0wk8ayb.png" alt="What each of the four guardrails does and the time it actually fired: hard budget twice, fail-stop as everyday backstop, blocked escalation once, step ceiling once" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ① Hard budget: &lt;code&gt;--max-budget-usd&lt;/code&gt; per round
&lt;/h3&gt;

&lt;p&gt;Put a spend ceiling on each round's process; hit it and the process is &lt;strong&gt;killed outright&lt;/strong&gt;, no negotiation. This one is required for the external-script form.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It fired twice in a single run.&lt;/strong&gt; I set the first round's ceiling at 5 and implementation got cut off partway; I checked the half-finished work on disk, confirmed it could be resumed, raised the ceiling to 8 and ran again — capped again; 12 finally got it through.&lt;/p&gt;

&lt;p&gt;The thing worth saying about being cut off is this: &lt;strong&gt;what's on disk is intact.&lt;/strong&gt; The documents landed, the state machine kept its ledger, and what I lost was "this round didn't finish," not "start over." Writing to disk plus keeping a ledger is what turns a blunt process kill into a pause you can resume from.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6g5mo8l2b0nej4xbwdk5.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6g5mo8l2b0nej4xbwdk5.png" alt="One budget-capped round: the process is cut off, but the documents and the state machine on disk are intact, so the next round resumes in place instead of starting over" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One honest note so those numbers don't get misread: &lt;strong&gt;5, 8 and 12 are ceilings I set per round, not what I actually paid.&lt;/strong&gt; I'm on a subscription billed by weekly volume, and per-token prices differ between vendors anyway. Treat those three as a rough sense of scale, not a price list — if you want real cost, look at token consumption and estimate it against your own vendor's published pricing.&lt;/p&gt;

&lt;h3&gt;
  
  
  ② and ④: stop when it's not ok, stop when the steps run out
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;fail-stop&lt;/strong&gt; covers the failure that's easiest to miss: &lt;strong&gt;a failed stage being treated as "done" by the next round&lt;/strong&gt;. Once that happens, every later round rests on a false premise, and the further it runs the worse it gets — all with a green light on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The step ceiling&lt;/strong&gt; guards against oscillation: break it, fix it, break it again, every round looking like work while nothing moves. Four steps by default = three convergence stages plus one for slack. I set it to 1 once, conservatively, and it stopped exactly as promised.&lt;/p&gt;

&lt;h3&gt;
  
  
  ③ blocked escalation: it really did stop when it should have
&lt;/h3&gt;

&lt;p&gt;If review turns up something that needs a product decision, it writes &lt;code&gt;blocked&lt;/code&gt; into the state machine, stops, and waits for a person.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The time this one fired is what convinced me the whole thing was trustworthy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During review it found that the three config fields added that round had &lt;strong&gt;no consumer anywhere in the backend&lt;/strong&gt;. The code was correct and the tests were green — this wasn't a bug, it was a product-level gap: should the fields be cut, or was the pipeline left unfinished? &lt;strong&gt;That's not a call the AI gets to make for me.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It didn't guess, and it didn't quietly delete the fields to keep the tests green — it wrote &lt;code&gt;blocked&lt;/code&gt;, stopped, and handed the question back. I decided to keep the fields and finish the pipeline, then let it continue. The follow-up surprised me: on the re-review it also fixed 2 genuine bugs in that pipeline implementation.&lt;/p&gt;

&lt;p&gt;It stopped where it should have, and it checked what it should have. That's what I wanted from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What that run produced
&lt;/h2&gt;

&lt;p&gt;The work was a three-phase iteration on a console project: 4 backend endpoint groups, 3 frontend pages, plus a notification ruleset. &lt;code&gt;TDD → implement → review&lt;/code&gt; ran unattended end to end, with &lt;strong&gt;301 tests passing and coverage above 87%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Human involvement came to three moments total: two verification calls when extending the budget, plus the one product decision at the block.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxf94sf8o1si3fwbsfmld.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxf94sf8o1si3fwbsfmld.png" alt="An afternoon on a timeline: after design sign-off, TDD, implementation and review run unattended; implementation is budget-capped twice, review stops once for a human decision, and the run ends at review-complete handed back to a person" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's an afternoon's worth of work, and I don't want to make it sound bigger than it was. But during the loop it was completely silent toward me — what I came back to wasn't a queue of "shall I do the next one?" but a terminal state. &lt;strong&gt;It isn't that it runs fast. It's that it doesn't need me present.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the line between human and machine sits
&lt;/h2&gt;

&lt;p&gt;The test hasn't changed since post 2: &lt;strong&gt;only hand the loop what can find its own errors.&lt;/strong&gt; Draw that line and two things never get handed over:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Figuring out what to build (human decision required).&lt;/strong&gt; PRD and design have to clear a human. That's a precondition for entering the loop, not a suggestion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shipping.&lt;/strong&gt; The loop's terminal state is review-complete; it stops there and a person decides whether to ship. &lt;code&gt;--autonomous&lt;/code&gt; has no effect on ship or deploy — once it's out, it's out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That marks off which work can be handed over. There's a companion question: &lt;strong&gt;once it's handed over, what keeps it from going off the rails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When post 1 covered prompt engineering, I gave that layer a ceiling: it's a soft constraint, the model may not fully follow you, and you may not notice at the time. Back then it was just a principle. This run gave it a concrete instance.&lt;/p&gt;

&lt;p&gt;Writing "go easy, watch the consumption" into a prompt is easy, but it belongs to the prompt layer — it can steer, it can't guarantee. &lt;code&gt;--max-budget-usd&lt;/code&gt; belongs to the process layer; it doesn't read what you wrote, it just cuts at the ceiling. Both overruns on this run were stopped by the latter, not talked down by the former.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anything that steers but doesn't guarantee eventually has to move up a layer.&lt;/strong&gt; This time it moved to a process argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next up
&lt;/h2&gt;

&lt;p&gt;If this post leaves you one thing, I'd like it to be this: &lt;strong&gt;to tell a real loop from a fake one, look at one thing only — whether the control flow lives in code or in the model's willingness.&lt;/strong&gt; A loop that turns around to ask you isn't a loop.&lt;/p&gt;

&lt;p&gt;Next post is about &lt;strong&gt;quality&lt;/strong&gt;: the pipeline runs fast and unattended, so why should anyone trust what comes out of it? What the red-test gate, the review gate and coverage each hold back — and what they still don't catch together.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Want to try it&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repo: &lt;a href="https://github.com/kanfu-panda/pdlc-skills" rel="noopener noreferrer"&gt;https://github.com/kanfu-panda/pdlc-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If it's useful, a star goes a long way ⭐&lt;/p&gt;




&lt;p&gt;I wrote these four guardrails straight off the record of that run, including the parts where it got cut off and the part where it got stuck. If it left you thinking "all right, this can actually be trusted," let me know. And if you've run loops yourself — smooth ones or crooked ones — the comments are open — happy to talk it through.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>agents</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Getting pdlc-skills Running in Your Own Project</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Sun, 30 Aug 2026 01:26:24 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/getting-pdlc-skills-running-in-your-own-project-4713</link>
      <guid>https://dev.to/kanfu-panda/getting-pdlc-skills-running-in-your-own-project-4713</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The first three posts were blueprints: what each layer is, where it lands, how they interlock. This one turns the other way — &lt;strong&gt;putting the blueprint onto your own project&lt;/strong&gt;. By the end you should be able to install it, know which command to start from, and get one feature through. There's one step in the middle that gets skipped constantly; I'll pull it out on its own, because skipping it makes the whole design from last post collapse.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That covers most of the theory. Now let's look at how pdlc-skills actually runs inside a real project.&lt;/p&gt;

&lt;p&gt;A lot of people have the same question first: do I need to backfill the tests? Write all the docs? If it's a codebase that's been running for two or three years, piled high, that nobody quite dares touch — does onboarding mean paying off the technical debt on day one?&lt;/p&gt;

&lt;p&gt;Here's the answer up front: &lt;strong&gt;none of that. Installing is one line, about a minute.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What will actually stall you is something else — the "so now what" right after install. The first project I onboarded, I sat staring at a screen full of commands starting with &lt;code&gt;/pdlc-&lt;/code&gt;, genuinely unsure which one to type. This post answers that "so now what": which command to start from, and which step you absolutely cannot skip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing: one line, two landing spots
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Global — every project on this machine can use it&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt;

&lt;span class="c"&gt;# Project-scoped — only this one repo&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; /path/to/my-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first three posts always gave the global line, because it's the shortest and hardest to get wrong. Here's &lt;strong&gt;when project-scoped is worth it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The only difference between the two is where it lands: &lt;code&gt;~/.claude/plugins/pdlc/&lt;/code&gt; or &lt;code&gt;&amp;lt;project&amp;gt;/.claude/plugins/pdlc/&lt;/code&gt;. What that buys you is real, though — project-scoped installs make &lt;strong&gt;the version travel with the repo&lt;/strong&gt;. Someone else clones it and gets the same version you have; and when you've got several projects open at once, one global upgrade doesn't move all of them at the same time.&lt;/p&gt;

&lt;p&gt;One person, one machine, not many projects? Go global, don't overthink it.&lt;/p&gt;

&lt;p&gt;Confirm it actually took, two steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; ~/.claude/plugins/pdlc/          &lt;span class="c"&gt;# where the global install lands&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &amp;lt;project&amp;gt;/.claude/plugins/pdlc/  &lt;span class="c"&gt;# where the project-scoped one lands&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seeing &lt;code&gt;skills/&lt;/code&gt; &lt;code&gt;references/&lt;/code&gt; &lt;code&gt;VERSION&lt;/code&gt; in there means you're good. Then type &lt;code&gt;/pdlc-&lt;/code&gt; in Claude Code and the dropdown should list 38 commands. If it does, you're installed.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ndvtdyxkqsm3zoar3uf.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ndvtdyxkqsm3zoar3uf.png" alt="Two landing spots: global goes in your home directory and covers every project, project-scoped goes in the repo and covers only that one" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Which starting point are you?
&lt;/h2&gt;

&lt;p&gt;38 commands spread out in front of you is intimidating, but &lt;strong&gt;you only need to recognize three the first time&lt;/strong&gt;. Which one depends on what you're holding:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your starting point&lt;/th&gt;
&lt;th&gt;First command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Brand-new project, no code yet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/pdlc-bootstrap&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Existing project, plenty of code&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/pdlc-adopt scan&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Already onboarded, day-to-day work&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/pdlc-feature&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Brand-new project&lt;/strong&gt; uses &lt;code&gt;/pdlc-bootstrap&lt;/code&gt;: give it one line of description and it picks a stack, generates the directory skeleton and draft documents. Good for when "I want to build an X" is still just an idea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Existing project&lt;/strong&gt; is where most people are, and it's the row I most want you to notice: the first command is &lt;code&gt;/pdlc-adopt scan&lt;/code&gt;, and &lt;strong&gt;scan is entirely read-only&lt;/strong&gt; — it surveys your stack, service layout, database, existing tests, and produces an onboarding report plus a health check, &lt;strong&gt;without changing a single byte&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I think that design is worth more than the feature itself. Letting AI touch a live legacy codebase makes anyone hesitate. So it splits "look" and "touch" into two commands: run &lt;code&gt;scan&lt;/code&gt;, read the report, and only if you like what you see do you run &lt;code&gt;/pdlc-adopt init&lt;/code&gt; to generate the baseline docs. The cost of trying it drops to zero.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx4c0c1pfveig3ldaqq4o.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx4c0c1pfveig3ldaqq4o.png" alt="Three starting points each take their own first command, then merge into the same main flow" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't skip this: settle what "passing" means, first
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This is the most important section in the post.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Last post covered the two boxes in the state file: the first box only takes &lt;strong&gt;exit codes from commands that really ran&lt;/strong&gt;, and the model's self-assessment sits in a second box, never part of the stop decision.&lt;/p&gt;

&lt;p&gt;Which raises a question — &lt;strong&gt;where do those commands come from?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer is &lt;code&gt;/pdlc-test-setup&lt;/code&gt;. It does four things: detect the stack, verify each command really runs, write them into &lt;code&gt;docs/00_standards/test-commands.yml&lt;/code&gt;, then scaffold the test directories and wire up local hooks.&lt;/p&gt;

&lt;p&gt;The repo is blunt about what this step is for: the whole thing hinges on "checks only accept exit codes, never the model's self-assessment," &lt;strong&gt;but until this point nothing has helped you stand that file up — and without it, the entire objectivity chain is empty&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It carries one non-negotiable rule: &lt;strong&gt;every command written into that file must have been really run once, with the exit code seen with your own eyes&lt;/strong&gt;. Guesses don't get written. The reasoning is the line I find most worth repeating —&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A command that "looks right but doesn't run" is &lt;strong&gt;worse than leaving it empty&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Empty, and everything downstream knows this stage has nothing to judge, so it stays honestly empty. A fake command that doesn't run hands every stage false checks — and the report still comes out green. There's a mirror image of the same idea: &lt;strong&gt;the most dangerous "auto-fix" is quietly blanking a check that was standing but broke&lt;/strong&gt; — the gate loosens on the spot and you can't tell.&lt;/p&gt;

&lt;p&gt;So what happens if you skip it? No commands to run → the first box must be left empty by rule → the stop decision has nothing to stand on → what you thought was "objective verification" has been the model feeling good about itself the whole time. &lt;strong&gt;The foundation for last post's design is this one step.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Worth mentioning: this file goes stale — scripts get renamed, tooling gets replaced, sub-projects come and go. You don't have to watch it; downstream stages will tell you when a command won't run, and you run &lt;code&gt;/pdlc-test-setup --refresh&lt;/code&gt; when you see the prompt.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8elvinfmrrgnrg3ucdom.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8elvinfmrrgnrg3ucdom.png" alt="Once test-commands.yml stands up, last post's " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running your first feature
&lt;/h2&gt;

&lt;p&gt;With the foundation in place, starting work takes one sentence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/pdlc-feature add phone verification to login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there it works down PRD → design → TDD → implementation → review, stopping and handing off at each stage. Fixing a bug is the same shape with &lt;code&gt;/pdlc-fix&lt;/code&gt;; to see where things stand, &lt;code&gt;/pdlc-status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Day to day, those three are all you use.&lt;/strong&gt; The other 35 are for when you want fine-grained control — rerun just the design stage, do a single code review, add a database design. Go find them then.&lt;/p&gt;

&lt;h2&gt;
  
  
  What shows up on disk, and what belongs in git
&lt;/h2&gt;

&lt;p&gt;After one round, a batch of directories appears under &lt;code&gt;docs/&lt;/code&gt;: requirements, design, testing, deployment, review each have their place, plus a &lt;code&gt;docs/.pdlc-state/&lt;/code&gt; holding one JSON per feature.&lt;/p&gt;

&lt;p&gt;Those first ones are documents; committing them is your call. But one of them &lt;strong&gt;has to go in&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;docs/.pdlc-state/&lt;/code&gt; should be committed to git. Don't put it in &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It looks like a cache — a dot-directory full of machine-read JSON, easy to wave off. It isn't a cache, it's &lt;strong&gt;the handoff&lt;/strong&gt;. Change sessions, change machines, hand the work to someone else: the only thing that can say "this feature is at this stage, and the last one passed" is that directory. Not in git means losing your memory every time you reopen a session; on a team, nobody else can see where you are.&lt;/p&gt;

&lt;p&gt;The repo calls it a "project delivery audit record." Treat it as an audit record and you stop wanting to ignore 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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fawby7xrfqemepubrodtq.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fawby7xrfqemepubrodtq.png" alt="The docs directory after a run, with the state-machine directory marked as must-commit" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two rules for onboarding an existing project
&lt;/h2&gt;

&lt;p&gt;If you came in from a legacy codebase, two rules are worth knowing on their own, because they decide whether this is realistic at all:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One: documents only, no code changes.&lt;/strong&gt; Not a line of business code is touched during onboarding — it only reverse-generates baseline documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two: incremental onboarding.&lt;/strong&gt; Existing code is marked "baselined" wholesale, and &lt;strong&gt;only new features go through the full flow&lt;/strong&gt;. You are not asked to clear the historical debt first.&lt;/p&gt;

&lt;p&gt;The second one is the load-bearing rule. I've watched plenty of process tools die on day one: you onboard, it reports several hundred existing violations, and one look at that number is enough to make people quit. Fence the existing code off and govern only what's new — that's what gives the process a chance of surviving to day two.&lt;/p&gt;

&lt;h2&gt;
  
  
  When not to use it
&lt;/h2&gt;

&lt;p&gt;Worth naming the boundary too. One-off scripts, throwaway demos, pure documentation repos — don't bother, the process doesn't pay for itself there. This is for projects that have to live a long time, get handed over, and answer for their quality.&lt;/p&gt;

&lt;p&gt;The test is simple: &lt;strong&gt;will anyone still open this project three months from now?&lt;/strong&gt; Yes, it's worth it. No, don't bother.&lt;/p&gt;

&lt;h2&gt;
  
  
  Walk it once
&lt;/h2&gt;

&lt;p&gt;Compressed into a single list you can follow directly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install&lt;/strong&gt;: &lt;code&gt;curl … | bash -s -- --global&lt;/code&gt; (swap in &lt;code&gt;--project &amp;lt;path&amp;gt;&lt;/code&gt; for multiple projects or team work)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt;: &lt;code&gt;ls ~/.claude/plugins/pdlc/&lt;/code&gt;, then type &lt;code&gt;/pdlc-&lt;/code&gt; in Claude Code and check for the 38 commands&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Know your starting point&lt;/strong&gt;: new project &lt;code&gt;/pdlc-bootstrap&lt;/code&gt;; existing project &lt;code&gt;/pdlc-adopt scan&lt;/code&gt; for the report, then &lt;code&gt;/pdlc-adopt init&lt;/code&gt; if you like it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stand up the foundation&lt;/strong&gt;: &lt;code&gt;/pdlc-test-setup&lt;/code&gt; — &lt;strong&gt;don't skip this one&lt;/strong&gt;, it decides whether every later "did it pass" is real or fake&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start work&lt;/strong&gt;: &lt;code&gt;/pdlc-feature &amp;lt;your one-line requirement&amp;gt;&lt;/code&gt;, with &lt;code&gt;/pdlc-status&lt;/code&gt; any time to see where it is&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit&lt;/strong&gt;: include &lt;code&gt;docs/.pdlc-state/&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Step 4 is the only one that looks postponable and isn't. The rest just go in order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next up: can it keep going on its own?
&lt;/h2&gt;

&lt;p&gt;Installed, started, foundation laid, first feature through — that's the line, end to end. If this post leaves you one thing, I'd like it to be this: &lt;strong&gt;settle what "passing" means before you start running&lt;/strong&gt; — get that order backwards and every bit of automation afterwards is spinning in place.&lt;/p&gt;

&lt;p&gt;Next is the heavy one in this series: &lt;strong&gt;it's installed and running, so can it go round after round on its own, without you watching?&lt;/strong&gt; That post covers the convergence loop's mechanics, its contracts, and four non-negotiable guardrails — including the time I got caught myself: talking the model out of burning tokens didn't work, and what finally caught it was a hard budget.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Want to try it&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repo: &lt;a href="https://github.com/kanfu-panda/pdlc-skills" rel="noopener noreferrer"&gt;https://github.com/kanfu-panda/pdlc-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If it's useful, a star goes a long way ⭐&lt;/p&gt;




&lt;p&gt;I wrote this in the order I actually onboarded my own projects, and spent extra words on the steps that tripped me up. If you get through it, tell me; if you get stuck somewhere, tell me that too and I'll fold it into the next version.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>agents</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>How Do the Three Engineering Paradigms Interlock in pdlc-skills?</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Sun, 23 Aug 2026 09:13:40 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/how-do-the-three-engineering-paradigms-interlock-in-pdlc-skills-38id</link>
      <guid>https://dev.to/kanfu-panda/how-do-the-three-engineering-paradigms-interlock-in-pdlc-skills-38id</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Last post ended with a yardstick: to tell whether a tool's three layers are genuinely joined, check whether they share one piece of state. This post cashes that in — &lt;strong&gt;the three layers never call each other, not once&lt;/strong&gt;. They hand off through a single file on disk. There's also a side effect I didn't see coming: because that file is split per feature, the pipeline doesn't only run one line downward, it fans out sideways and runs several at the same time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Last post placed each layer inside &lt;a href="https://kanfu-panda.github.io/pdlc/" rel="noopener noreferrer"&gt;pdlc-skills&lt;/a&gt;: the rules every command shares are the prompt layer, the stretch that advances on its own is the loop layer, the stage order and the relation graph are the graph layer.&lt;/p&gt;

&lt;p&gt;But knowing who governs what is not the same as knowing how they fit together.&lt;/p&gt;

&lt;p&gt;Following that thought, the most direct move is to go into the code and find the call — where Graph calls Loop, where Loop calls the prompt layer. You won't find it. There is not one line of code in which these three layers reference each other.&lt;/p&gt;

&lt;p&gt;So how do they end up working together?&lt;/p&gt;

&lt;h2&gt;
  
  
  The key is timing, not calling
&lt;/h2&gt;

&lt;p&gt;The three layers don't need to know each other, because &lt;strong&gt;they don't act at the same moment&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;When it acts&lt;/th&gt;
&lt;th&gt;What it governs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Graph&lt;/td&gt;
&lt;td&gt;at stage &lt;strong&gt;boundaries&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;whether you may enter the next step&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;inside&lt;/strong&gt; one invocation&lt;/td&gt;
&lt;td&gt;what the model sees this time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loop&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;between&lt;/strong&gt; stages&lt;/td&gt;
&lt;td&gt;whether another round is needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An analogy: Graph checks tickets at the door, the prompt layer does the talking inside the hall, Loop stands outside counting how many sets are left. The three never speak to each other. They go by the same scoreboard.&lt;/p&gt;

&lt;p&gt;That scoreboard is the file on disk.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F75os8d8ks7ux6deteci8.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F75os8d8ks7ux6deteci8.png" alt="Three swim lanes on a timeline: Graph appears only at stage boundaries, the prompt layer expands inside each invocation, Loop sits between two stages" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Following one feature all the way through
&lt;/h2&gt;

&lt;p&gt;Enough abstraction. Here's a real feature from start to convergence, one beat at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beat one: the opening move.&lt;/strong&gt; A new feature has just been declared and there is nothing on disk yet. Exactly one command can pick it up — write the requirements. Why? Because every other command declares which prior document it needs: design needs requirements, tests need design, and not one of those preconditions is satisfied. &lt;strong&gt;This isn't advice to "write requirements first," it's that without the prior artifact you cannot get through the door.&lt;/strong&gt; That's Graph doing its job, and its job is only "do I let you in."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beat two: doing the work.&lt;/strong&gt; Once you're through the door, Graph steps off and the floor belongs to the prompt layer. In this one invocation, the model sees more than the command's own text — it also sees the full set of rules shared by every command: artifacts must land on disk, self-check before handing off, fix once and don't recurse. Those rules live in one place and expand in at call time, rather than being copied into each command.&lt;/p&gt;

&lt;p&gt;What comes out isn't free-form prose either. The filename, the directory, the sections — all fixed; and the document carries a small identity header at the top saying which feature it belongs to, which stage it's in, and which document came before it. I won't unpack the format here; what matters is what it buys you: &lt;strong&gt;the artifact carries its own coordinates&lt;/strong&gt;, so you can walk backwards from it all the way to the original requirement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beat three: closing out by writing to disk.&lt;/strong&gt; This is the critical beat. Finishing the main work isn't the end of it — the command has to record a line in that file: I've finished this stretch, here's how it went, here's who picks it up next. The file sits on disk, &lt;strong&gt;one per feature&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beat four: the stop decision.&lt;/strong&gt; Only now does the loop appear, and it reads nothing but that file — not the code, not the artifacts, not the chat log. It reads and emits one result: which command runs next, or "done," or "blocked." The outer script takes that result, runs the next command, and we're back at beat three.&lt;/p&gt;

&lt;p&gt;Once review is complete the loop stops, emits "done," and waits for a human. Shipping and deploying are never inside the loop — once it's out, you can't pull it back, and what it touches is real users in production.&lt;/p&gt;

&lt;p&gt;So the whole chain has exactly three handoffs, and what crosses each one is &lt;strong&gt;a name, not a call&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what Graph hands the invocation: "here's the stretch you're on";&lt;/li&gt;
&lt;li&gt;what the invocation hands the disk: "I'm done, here's how it went";&lt;/li&gt;
&lt;li&gt;what the disk hands the loop: "keep going or not."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of the three ever touches another.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsvxrvos3nufu3ticsm34.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsvxrvos3nufu3ticsm34.png" alt="Three handoff points: Graph hands over which stretch to work on, the stage writes its result to disk on close, and the loop reads from disk whether to keep going" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The one design in that file that matters most
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What was actually run and what the model says about itself go in two separate boxes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first box takes only results from commands that really ran: did tests pass, is coverage high enough, is lint clean — all booleans translated from exit codes. If a stage has no command to run at all (requirements and design produce documents only), the box stays empty; you may not fill in "passed" because "I feel this went well."&lt;/p&gt;

&lt;p&gt;The second box is the model's own self-check, recording only how many items failed. &lt;strong&gt;Reference only. Never part of the stop decision.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Where's the difference? The loop's stop decision reads the first box and nothing else. Which means the model's self-assessment is excluded from the stop path at the level of the data structure, not by a line asking it to please report honestly. Whatever it writes in the second box cannot change whether this round stops.&lt;/p&gt;

&lt;p&gt;That's what "the three layers share one piece of state," from last post, actually comes down to.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkdie8pfk3ft2ec02t0k9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkdie8pfk3ft2ec02t0k9.png" alt="The two boxes in the state file: one holds only results from commands that really ran and decides whether to stop, the other holds the model's self-check for reference only" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The real loop has two levels
&lt;/h2&gt;

&lt;p&gt;Time to admit something: the loop drawn above is only the &lt;strong&gt;inner loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When I actually put this to work, the shape looks like this —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lead agent: overall design → split into N mutually independent features
    ↓
Outer script: start one loop per feature
    ↓
Inner loop × N (each on its own feature)   ← running at the same time
    ↓
Each stops at "review complete" or "blocked" → a human collects the results and decides on shipping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lead agent does the overall design and splits the work into a set of mutually independent features. The outer script starts an inner loop per feature. Those loops run forward in parallel, each stopping at its own endpoint. Finally a human gathers up the N results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes it safe to run them at the same time?&lt;/strong&gt; The precondition is that what you split out really is &lt;strong&gt;relatively independent features&lt;/strong&gt; — no dependencies between them, or there's no parallelism to speak of. Given that, the state files are split per feature too: one feature, one file, no cross-dependency.&lt;/p&gt;

&lt;p&gt;Feature IDs use "date + hours-minutes-seconds" rather than the day's sequence number. The reason spelled out in the repo: when several people or several AIs start work at the same time, each one grabbing "today's highest number plus one" is guaranteed to collide, and colliding state files with the same name have to be renumbered by hand. Switch to the timestamp of the moment of creation and independent copies almost never collide. This ID format was built for parallelism from the start — I just didn't think of it as a piece of design at the time, only as a small trick against collisions.&lt;/p&gt;

&lt;p&gt;The code has to be isolated too: each feature's inner loop runs in its own git worktree, out of everyone's way, with artifacts going through separate PRs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So why must the split stay with a human, or with the lead agent?&lt;/strong&gt; Last post gave the test: hand the loop whatever can find its own errors, keep the rest with people. "How many features should this batch of requirements split into, and which depend on which" — get it wrong and no command reports an error. It's a judgment call, not a check. So it lives outside the loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The two levels also end differently&lt;/strong&gt;: the inner loop ends at review complete, the outer one ends when all N have converged. And shipping remains the single human gate — no matter how many ran at once, the person is still the one who presses it.&lt;/p&gt;

&lt;p&gt;I've run this for real on a command-line tool project of my own. How to get it running, how the guardrails are set, what an overnight run actually produces — later posts cover that. This one only draws the shape.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6tjy90ezc1dwuixaoysy.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6tjy90ezc1dwuixaoysy.png" alt="Two-level loop: the lead agent splits work into N relatively independent features, the outer script starts an inner loop each in its own worktree, and everything converges on a human shipping gate" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next up: getting it running in your own project
&lt;/h2&gt;

&lt;p&gt;If this post leaves you with one line, I'd like it to be this: &lt;strong&gt;the three layers interlock not because they call each other, but because they write into different boxes of the same file.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The interface is a name, not a function — which is why changing one layer doesn't ripple into another, and why this pipeline can be copied sideways several times over.&lt;/p&gt;

&lt;p&gt;I deliberately didn't drill down here: which fields that state file actually has, how the loop's guardrails and limits are set, how parallel runs are closed out — all of that is for later posts. &lt;strong&gt;Get the shape clear first, then look at the parts.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That covers it: what the three layers are, where each one lands, and how they interlock — three posts. Next post turns in a different direction: &lt;strong&gt;in your own project, how to install it, how to start, and how to bring an existing codebase in&lt;/strong&gt; — from this post's blueprint to the first command that actually runs in your terminal.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Want to try it&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh &lt;span class="se"&gt;\&lt;/span&gt;
  | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repo: &lt;a href="https://github.com/kanfu-panda/pdlc-skills" rel="noopener noreferrer"&gt;https://github.com/kanfu-panda/pdlc-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If it's useful, a star goes a long way ⭐&lt;/p&gt;




&lt;p&gt;That two-level diagram is how I actually run this; it lived only in my head until I drew it. If it gave you a concrete picture, a reaction helps. And if someone near you is working out how to get AI to do several things at once, pass it along.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>agents</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Why Does pdlc-skills Fit All Three Engineering Paradigms So Naturally?</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Thu, 13 Aug 2026 22:56:54 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/why-does-pdlc-skills-fit-all-three-engineering-paradigms-so-naturally-50b6</link>
      <guid>https://dev.to/kanfu-panda/why-does-pdlc-skills-fit-all-three-engineering-paradigms-so-naturally-50b6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Once the three concepts are sorted out, the next question is the interesting one: is there anything real where all three layers grew in together? This post holds one up against them — &lt;a href="https://kanfu-panda.github.io/pdlc/" rel="noopener noreferrer"&gt;pdlc-skills&lt;/a&gt;, the thing I've been building. Conclusion first: the fit &lt;strong&gt;is a coincidence&lt;/strong&gt;. But there's a reason behind the coincidence, and that reason is what this post is about.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Last time we separated three terms that get mixed up constantly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prompt engineering governs how you talk to the model this one time;&lt;/li&gt;
&lt;li&gt;loop engineering governs how many rounds a thing repeats and what condition stops it;&lt;/li&gt;
&lt;li&gt;graph engineering governs which steps along the path can't be skipped.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They're not on the same level. It isn't a choice of one — they stack.&lt;/p&gt;

&lt;p&gt;Which raises the obvious question: all three sound reasonable, but &lt;strong&gt;is there anything real where all three layers grew in together&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Let's hold one up against them — pdlc-skills, the thing I've been building.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is pdlc-skills?
&lt;/h2&gt;

&lt;p&gt;It's a &lt;a href="https://docs.anthropic.com/" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; plugin, and what it does fits in one line: &lt;strong&gt;it turns AI-written code from something you chatted about into something that lands on disk.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install it and you get 38 slash commands, one per stage of the workflow. The one you'll use most is &lt;code&gt;/pdlc-feature&lt;/code&gt; — start a new feature with it and the AI works down the line: PRD → design → TDD → implementation → review → ship, stopping to hand off at each stage.&lt;/p&gt;

&lt;p&gt;Three things separate it from "hey, build me this feature":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Artifacts must land on disk.&lt;/strong&gt; PRD, design, review notes are real files under &lt;code&gt;docs/&lt;/code&gt;, not a passage in a chat transcript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every feature carries state.&lt;/strong&gt; Which stage it's at, whether the last one passed — all recorded on disk. Pick it up in a new session and it knows where it is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests must be red first.&lt;/strong&gt; No failing test, no implementation. That's a hard gate, not a suggestion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MIT licensed. It's most complete on Claude Code; the same methodology runs on other AI coding tools through adapters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Its origins are unremarkable
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I didn't design these three layers in. I hadn't even heard the terms "loop engineering" or "graph engineering" when I built it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It just follows the product development lifecycle that software engineering already had. Requirements, design, tests, implementation, review, ship — that flow has been lying around the industry for decades, and there's nothing new in it. All I did was translate it for the AI: what each stage does, what it produces, what counts as passing, written out as commands, so the AI works down the flow instead of wherever its attention lands.&lt;/p&gt;

&lt;p&gt;One rule came with it: &lt;strong&gt;every stage has to write something to disk.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PRDs go to &lt;code&gt;docs/01_requirements/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Designs go to &lt;code&gt;docs/02_design/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Review notes go to &lt;code&gt;docs/07_reviews/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Each feature also gets its own state file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All plain text. You can open any of it, and you can &lt;code&gt;git diff&lt;/code&gt; exactly what the AI did this round.&lt;/p&gt;

&lt;p&gt;Then these new terms started circulating. I held them up against what I'd built and found matches everywhere — not because I built toward them, but because it had grown that way on its own.&lt;/p&gt;

&lt;p&gt;So let's go layer by layer, in order: prompt, loop, graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔵 Prompt layer: matches "one copy of the spec"
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it corresponds to in the flow.&lt;/strong&gt; Software engineering has an old rule: there's one copy of the spec, not one version here and a different one there. Applied to pdlc, that means the rules every command has to honor — artifacts land on disk, self-check before handoff, repair only once — can't be written out separately inside each command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it's actually done.&lt;/strong&gt; Common rules are pulled into fragments and expanded into each skill at build time. Currently that's &lt;strong&gt;13 fragments compiled into 36 of the 38 skills&lt;/strong&gt; (the two without them are &lt;code&gt;pdlc-loop-next&lt;/code&gt; and &lt;code&gt;pdlc-status&lt;/code&gt; — too light to share anything). The six invariants — files must land on disk, each stage must be recorded (appending to history), tests must be red first, self-check is mandatory, repair happens once, and state must advance (&lt;code&gt;current_stage&lt;/code&gt; has to actually change, so an outer loop can't spin on a stale value) — live in one of those fragments. Change it once, everything changes.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv4uzae1somos85e7w2qh.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv4uzae1somos85e7w2qh.png" alt="13 shared fragments expand into 36 skills at build time; one edit propagates everywhere" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which layer it matches.&lt;/strong&gt; Prompt engineering governs what the model sees this time. Nothing about that changed here — it's just managed the way you'd manage code: extract the common part, expand at build time, single source of truth.&lt;/p&gt;

&lt;p&gt;The new term is prompt engineering; the old rule is single source of truth. Same thing, two vocabularies — &lt;strong&gt;that's coincidence number one&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Loop layer: matches the TDD red-light gate
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it corresponds to in the flow.&lt;/strong&gt; TDD is old news in software engineering, and the rule is one line: write a failing test, then write the implementation, until the test goes green. pdlc copies that straight across — no red test, no implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What that rule brings with it.&lt;/strong&gt; Writing tests before implementation means "is it done" gets an answer that has nothing to do with the model: run it, exit code 0 means it passed, anything else means it didn't.&lt;/p&gt;

&lt;p&gt;What makes that answer valuable is that it doesn't route through the model. Ask the model that wrote the code to grade its own code and it will grade generously and consistently — not because it's lying, but because it genuinely thinks the code is fine. So in pdlc the model's self-check is recorded separately, treated as a reference, and &lt;strong&gt;never as grounds for stopping&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which is why this stretch can go to a loop&lt;/strong&gt;: &lt;code&gt;tdd → implement → review&lt;/code&gt; runs on its own until review passes. The PRD and design before it can't — whether to build this feature at all, how many modules to split it into, where the boundary goes, are judgment calls, and no command returns an exit code for those. Judgment calls stay with the human. That line is drawn clearly.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9dwhsivfqq1swfw983jr.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9dwhsivfqq1swfw983jr.png" alt="Which stretch of the flow can be handed to a loop and which must stay with a human, with the criteria alongside" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which layer it matches.&lt;/strong&gt; Loop engineering has a line you can treat as an axiom: a loop is a task with a check; a task without a check is just hope. TDD is exactly that check.&lt;/p&gt;

&lt;p&gt;I do TDD because software engineering says test before you write, &lt;strong&gt;not to prepare a straightedge for a loop&lt;/strong&gt;. But the straightedge was sitting right there — &lt;strong&gt;coincidence number two&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Guardrails, step limits, budgets — I'm saving those for post five.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟣 Graph layer: matches stage gating and review
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it corresponds to in the flow.&lt;/strong&gt; The phrase "lifecycle" carries order in it: requirements before design, design before implementation, review after implementation, ship after review. In software engineering that order isn't advice, it's discipline — the industry has already paid decades of tuition for skipping steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it's actually done.&lt;/strong&gt; Each stage writes its state to disk on completion; the next stage reads that state first and won't start unless the preconditions hold. No skipping tests to implement. No shipping without review.&lt;/p&gt;

&lt;p&gt;Beyond the vertical order there's a horizontal layer: how features relate to each other. &lt;code&gt;/pdlc-relate&lt;/code&gt; records those relationships explicitly, with &lt;strong&gt;six directed edge types&lt;/strong&gt; — extends, depends on, supersedes, resolves, conflicts with, relates to. Then &lt;code&gt;impact &amp;lt;feature-id&amp;gt;&lt;/code&gt; gives you the blast radius in one command: 🔴 directly depends on it, 🟡 one hop away, 🟢 already finished, ignore 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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1x1rjzg6nxrmrc02kkg9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1x1rjzg6nxrmrc02kkg9.png" alt="The vertical axis is a linear pipeline with gates; the horizontal one is the actual directed graph" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And here's the honest part.&lt;/strong&gt; That vertical line isn't a graph, strictly speaking. It's a linear pipeline with a few gates: no conditional branches, no parallel nodes, no rolling back to an arbitrary point — nearly nothing that makes a graph a graph. The thing that actually qualifies is the horizontal dependency graph: directed, traversable, cycle-detectable, and able to catch references pointing at features that don't exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which layer it matches.&lt;/strong&gt; So why does the vertical count as the graph layer at all? Because &lt;strong&gt;the essence of the graph layer isn't "drawn as a graph," it's negative constraint&lt;/strong&gt; — declaring which paths are off limits. To reuse the line from last time: the track doesn't plan your trip, it just makes certain directions impossible.&lt;/p&gt;

&lt;p&gt;Stage gates constrain order, the dependency graph constrains blast radius; both do the same job. And "advance by stage, review at key points" was written into the flow by software engineering a long time ago — &lt;strong&gt;coincidence number three&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fes3t7711v1aa0ddvr57x.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fes3t7711v1aa0ddvr57x.png" alt="Six directed edge types form the graph; impact marks the blast radius by distance" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Three coincidences stop being a coincidence
&lt;/h2&gt;

&lt;p&gt;One match could be luck. Three matches is worth asking about.&lt;/p&gt;

&lt;p&gt;My answer: &lt;strong&gt;these two things were solving the same set of problems all along.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The three paradigms are new vocabulary, distilled over the last couple of years out of AI agent practice. The software engineering flow was beaten into shape over decades by real projects. And the mistakes humans and AI make on engineering work overlap heavily — working wherever attention lands, keeping several copies of the spec, declaring something done without verifying it, changing one thing without knowing what else breaks. The rules the old flow set up to treat those still work when you translate them onto an AI.&lt;/p&gt;

&lt;p&gt;So the constraints the new vocabulary describes had already been written down, in another language:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What the three paradigms say&lt;/th&gt;
&lt;th&gt;What software engineering already required&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prompt engineering: unify the context&lt;/td&gt;
&lt;td&gt;One copy of the spec, don't scatter it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loop engineering: needs an objective check&lt;/td&gt;
&lt;td&gt;Write the test before the implementation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graph engineering: apply negative constraints&lt;/td&gt;
&lt;td&gt;Advance by stage, review at key points&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;That's what "fits naturally" means here&lt;/strong&gt;: I didn't fit three layers into it. The old flow already had those three layers — nobody had called them by these three names before.&lt;/p&gt;

&lt;p&gt;There's one more thing, which the old flow didn't have and which showed up on its own during implementation: &lt;strong&gt;the three layers ended up sharing one thing — the state on disk.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The graph reads it to know which step it's on,&lt;br&gt;
the loop reads it to know whether this round advanced anything,&lt;br&gt;
the prompt reads it to get the context for this call.&lt;/p&gt;
&lt;/blockquote&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9moyof47loq4o11axng1.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9moyof47loq4o11axng1.png" alt="The three layers share one state file on disk" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which hands you a ready-made test: &lt;strong&gt;to judge whether a tool's three layers are genuinely joined, check whether they share one state.&lt;/strong&gt; Sharing is integration; each keeping its own is three mechanisms living in the same repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next up: when does each one actually kick in?
&lt;/h2&gt;

&lt;p&gt;If this post leaves you with one line, I'd like it to be this: &lt;strong&gt;if you want AI to do engineering work, you'll get further picking up the engineering process you already have than inventing a new framework.&lt;/strong&gt; That process isn't new, but the ailments it treats, AI has too.&lt;/p&gt;

&lt;p&gt;Now that we know where each layer landed, the next question is: &lt;strong&gt;in one real feature, when does each of them actually kick in?&lt;/strong&gt; Next post follows a single feature from start to finish, marking the timeline for all three layers and how they hand off to each other.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Want to try it&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh &lt;span class="se"&gt;\&lt;/span&gt;
  | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Project page: &lt;a href="https://kanfu-panda.github.io/pdlc/" rel="noopener noreferrer"&gt;kanfu-panda.github.io/pdlc&lt;/a&gt; · Source: &lt;a href="https://github.com/kanfu-panda/pdlc-skills" rel="noopener noreferrer"&gt;github.com/kanfu-panda/pdlc-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If it's useful, a star goes a long way ⭐&lt;/p&gt;




&lt;p&gt;If this gave you a concrete picture of how the three layers land, a reaction or a follow helps. And if someone near you is working out how to get AI to follow a process, pass it along.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>agents</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Prompt Engineering, Loop Engineering, Graph Engineering: What Are They?</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Sun, 09 Aug 2026 04:19:57 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/prompt-engineering-loop-engineering-graph-engineering-what-are-they-40i2</link>
      <guid>https://dev.to/kanfu-panda/prompt-engineering-loop-engineering-graph-engineering-what-are-they-40i2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Prompt engineering, loop engineering, graph engineering — these three keep landing in the same comparison table, as if you had to pick one. But they don't operate at the same level. Sorting that out is worth more than mastering any one of them. This post isn't about any specific tool. It covers what each layer actually governs, where each one hits its ceiling, and ends with three questions that tell you which layer your problem belongs to.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Three terms, three separate origins
&lt;/h2&gt;

&lt;p&gt;These three came from completely different places, so let's start there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt engineering&lt;/strong&gt; got renamed somewhere along the way. Early on the discussion was about phrasing — what persona to assign, which magic words to use. Then people realized phrasing wasn't what decided the outcome; what the model got to see was. Hence the more accurate label going around now: context engineering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loop engineering&lt;/strong&gt; spread through the community on the back of Ralph-style setups. The mechanics are almost disappointingly simple: a one-line &lt;code&gt;while&lt;/code&gt; loop that feeds the same instruction to the model over and over, lets the tests decide right from wrong, and after enough rounds the version that passes acceptance simply surfaces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Graph engineering&lt;/strong&gt; arrived with orchestration frameworks like LangGraph, which argue for drawing an agent's execution path explicitly — who hands off to whom, whether you can go back, where it has to stop.&lt;/p&gt;

&lt;p&gt;Three separate threads, eventually shoved into the same table for comparison. The table is exactly where things go wrong — these aren't the same kind of thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧱 They aren't on the same level
&lt;/h2&gt;

&lt;p&gt;The relationship isn't side-by-side. It's &lt;strong&gt;stacked&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What it governs&lt;/th&gt;
&lt;th&gt;Granularity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Graph engineering&lt;/td&gt;
&lt;td&gt;How paths are organized&lt;/td&gt;
&lt;td&gt;Stage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loop engineering&lt;/td&gt;
&lt;td&gt;How iteration converges&lt;/td&gt;
&lt;td&gt;Round&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt engineering&lt;/td&gt;
&lt;td&gt;How a single exchange goes&lt;/td&gt;
&lt;td&gt;Token&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2jbaihg9j2ndh0708nux.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2jbaihg9j2ndh0708nux.png" alt="Graph on top, Loop in the middle, prompt at the bottom, with control granularity narrowing from stage to token" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing has to be said right here, or you fall into the next trap: &lt;strong&gt;the stack being real doesn't mean every layer is required.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once "the standard three-layer architecture" lodges in your head, every task starts looking like it needs all three. In practice, plenty of systems that work well have only one or two:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Shape&lt;/th&gt;
&lt;th&gt;When it looks like this&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prompt only&lt;/td&gt;
&lt;td&gt;One-shot classification, extraction, rewriting — any orchestration is a net loss&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt + Loop&lt;/td&gt;
&lt;td&gt;Iterate against tests; the path was never drawn at all&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt + Graph&lt;/td&gt;
&lt;td&gt;The path can be fully enumerated; no autonomous iteration needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;All three&lt;/td&gt;
&lt;td&gt;Production-grade engineering workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Anthropic's principle in &lt;em&gt;Building effective agents&lt;/em&gt; is a practical one: start with the simplest solution, and only add complexity when it demonstrably improves things.&lt;/p&gt;

&lt;p&gt;So the right mental model isn't "a three-layer architecture." It's — &lt;strong&gt;three optional nested layers. Start at the bottom by default, and understand that going up costs you something.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo6hff5z576l5777ywmvl.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo6hff5z576l5777ywmvl.png" alt="Four common shapes: prompt only, prompt plus loop, prompt plus graph, and all three, each with a typical task" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Layer by layer: what each one actually governs
&lt;/h2&gt;

&lt;p&gt;Four things per layer below: what it is, how it's done, one thing people get backwards, and where the ceiling is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt engineering: deciding what the model sees this time
&lt;/h3&gt;

&lt;p&gt;It stopped being about "phrasing things nicely" a while ago. What you're really managing is which things the model gets to see this time, and which it doesn't.&lt;/p&gt;

&lt;p&gt;The reason it evolved that way is straightforward: once a task spans multiple rounds of reasoning, a well-turned sentence stops being enough, and the job shifts to managing the whole context state — system instructions, tool definitions, external data, message history, all of it.&lt;/p&gt;

&lt;p&gt;In practice there are only a handful of moves. The system prompt needs to sit at the right altitude: specific enough to actually steer behavior, without hard-coding every situation — rules that are too granular start contradicting each other the moment something unforeseen shows up, and rules that are too vague say nothing at all. Tool descriptions need to make clear what each tool is for; the more overlap between tools, the more often the model picks wrong. Agree on the output format up front so you're not writing regexes later. Give a diverse handful of examples rather than piling up edge cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What people get backwards&lt;/strong&gt;: longer context isn't better. The fuller you pack it, the more the middle gets diluted — that's a real, measurable decay, not the model "not being smart enough." Attention is a budget, and where you spend it is a tradeoff, not a "more is safer" situation. Working out what the model doesn't need to see this time is often easier than working out what to say.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ceiling&lt;/strong&gt;: it's a soft constraint. The model may not follow you exactly, and you may not be able to tell at the time.&lt;/p&gt;

&lt;p&gt;This layer's biggest strength and biggest problem are the same fact — one edited sentence takes effect immediately, which also means you're relying on the model's willingness.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loop engineering: a task, plus one check
&lt;/h3&gt;

&lt;p&gt;There's a line here you can treat as an axiom:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A loop is a task with a check. A task without a check is just hope.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ralph's shape came up earlier: it's that one &lt;code&gt;while&lt;/code&gt; line. But the real design isn't in the loop — &lt;strong&gt;it's in the files around it&lt;/strong&gt;, three of them, each doing one job. A spec, stating what this project should end up being and what's off limits. A progress list, recording what's done and what's next. And one instruction, fed in verbatim every round, telling the model: read the other two first, then pick one thing and do it. The loop itself is trivial; getting those three files right is the hard part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What people get backwards&lt;/strong&gt;: the context is wiped clean every round — the model has no memory of what it did last time. That sounds like a defect. It's a feature. Amnesia guarantees every round starts from a clean slate, so a wrong interpretation from one round doesn't get carried the rest of the way. The price is that anything that has to survive across rounds must live on disk — that progress list isn't a note for humans, it's the model's only memory going into the next round.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where the stop signal comes from&lt;/strong&gt;: how does a loop know it's done? It needs a signal something can decide automatically — test exit codes, compiler output, type checks. "Looks fine to me" doesn't count, because you can't put that in a conditional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it typically crashes&lt;/strong&gt;, two ways. One is spinning: every round the model feels like it did something, nothing actually moves, and tokens burn with nothing to show. The other is redoing work: it doesn't find what the last round already built, assumes it isn't there, and builds it again — like a contractor who doesn't see yesterday's pipe, breaks up the floor, and lays it a second time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ceiling&lt;/strong&gt;: a loop with no verification signal is mass-producing garbage. And its failures are the hardest to catch — it keeps running, it's just heading the wrong way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Graph engineering: two different things with the same name
&lt;/h3&gt;

&lt;p&gt;There's an ambiguity to clear up first. "Graph" refers to two completely different things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Orchestration graphs&lt;/strong&gt;: the LangGraph kind, drawing which path the flow takes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge graphs&lt;/strong&gt;: the GraphRAG / code-relationship kind, drawing how entities relate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same word, different objects. This post is about the first one. The second gets its own post — number seven in this series.&lt;/p&gt;

&lt;p&gt;What an orchestration graph does is move "what order does this work go in" out of your head and onto paper: who picks up whose output, which step can be sent back, which step has to stop and wait for a human to nod.&lt;/p&gt;

&lt;p&gt;There are five common shapes, each fitting a class of work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sequential&lt;/strong&gt;: one step after another. Writing code works this way — design first, then tests, then the implementation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing&lt;/strong&gt;: classify first, then decide who handles it. Tickets come in, get sorted, refunds go down the refund path, outages down the outage path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel&lt;/strong&gt;: independent pieces run at once, then get merged. Have the same diff reviewed separately for security, performance, and readability, then combine the notes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orchestrator with workers&lt;/strong&gt;: one splits and assigns, several put their heads down and do it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluator-optimizer&lt;/strong&gt;: run the output through a review; if it fails, send it back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real systems are basically these five in combination. You don't need to invent new ones.&lt;/p&gt;

&lt;p&gt;Drawing the graph has two benefits people overlook. One is &lt;strong&gt;recoverability&lt;/strong&gt; — every node can be checkpointed, so a crash resumes from the last checkpoint instead of the top. The other is &lt;strong&gt;auditability&lt;/strong&gt; — afterwards you can explain why it took that path, which matters when someone's going to ask.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What people get backwards&lt;/strong&gt;: it dictates which paths are off limits, not how to do the work. More on that below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ceiling&lt;/strong&gt;: it can only express what you thought of in advance. Anything requiring judgment on the spot, anything you haven't seen before — the graph is useless. There's also a hidden cost: once drawn, the graph becomes a liability, and reality shifting means redrawing it. Redrawing costs a lot more than editing a sentence, so it's worth planning before you start.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk3parjhn5s4wavvn3clt.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk3parjhn5s4wavvn3clt.png" alt="A quick-reference card with one definition, one representative practice, and one ceiling per layer" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🏠 The same thing, told as a renovation
&lt;/h2&gt;

&lt;p&gt;Let's run all three through one analogy:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;What it maps to in a renovation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prompt engineering&lt;/td&gt;
&lt;td&gt;How you tell the contractor what you want&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loop engineering&lt;/td&gt;
&lt;td&gt;Do it → inspect → fails → redo → inspect again&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verification signal&lt;/td&gt;
&lt;td&gt;The inspector's straightedge, spirit level, flood test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graph engineering&lt;/td&gt;
&lt;td&gt;The trade sequence (plumbing → waterproofing → flood test → tiling → carpentry → paint)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human checkpoint&lt;/td&gt;
&lt;td&gt;The owner showing up to sign off at key moments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context wiped each round&lt;/td&gt;
&lt;td&gt;A new contractor showing up every morning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three sentences for the three personalities:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A prompt is the brief.&lt;/strong&gt; "North-facing wall in the main bedroom, off-white, two coats, tape the edges." Costs nothing, works immediately — but the contractor may decide close enough is close enough, and you won't catch it on the spot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A loop is the redo mechanism.&lt;/strong&gt; Briefing alone doesn't get you there; you need inspection. The key word isn't "redo," it's the straightedge — redoing without one is just doing it twice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A graph is the trade sequence.&lt;/strong&gt; It won't tell you what color the wall should be. It just makes "tiling before waterproofing" impossible as a matter of process.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdxxhg16nc8rtq4l3cjbe.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdxxhg16nc8rtq4l3cjbe.png" alt="The renovation flow mapped onto the three layers: briefing, redo-and-inspect, and the trade sequence" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One line for how the three divide the work: &lt;strong&gt;sequence rules out what you can't do, redoing forces it up to standard, the brief decides how it actually gets done.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚖️ Three personalities, three ways to crash
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Prompt engineering&lt;/th&gt;
&lt;th&gt;Loop engineering&lt;/th&gt;
&lt;th&gt;Graph engineering&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Who's in control&lt;/td&gt;
&lt;td&gt;The model&lt;/td&gt;
&lt;td&gt;The model (you only set the stop condition)&lt;/td&gt;
&lt;td&gt;You (you draw the path, the model fills it in)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Determinism&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Lowest&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Up-front investment&lt;/td&gt;
&lt;td&gt;Minimal&lt;/td&gt;
&lt;td&gt;Low, but you need a verification setup first&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unit cost&lt;/td&gt;
&lt;td&gt;1x&lt;/td&gt;
&lt;td&gt;4x, 15x for multi-agent&lt;/td&gt;
&lt;td&gt;2–3x, but fewer detours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debuggability&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Worst&lt;/td&gt;
&lt;td&gt;Best&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical failure&lt;/td&gt;
&lt;td&gt;The model doesn't comply&lt;/td&gt;
&lt;td&gt;Drifts and nobody notices&lt;/td&gt;
&lt;td&gt;Wrong graph, or too rigid&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;A note on the cost row: roughly 4x for agents and 15x for multi-agent come from Anthropic's public write-up; the 2–3x for graphs is a rough figure circulating in public material. These are order-of-magnitude references, not measurements.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The row worth sitting with is the last one. &lt;strong&gt;The three failure modes are nothing alike&lt;/strong&gt;: a prompt failure you can see — it didn't comply, it's right there. A loop failure you can't see — it's still running, just pointed the wrong way. A graph failure you can't change — the graph is set and reality moved.&lt;/p&gt;

&lt;p&gt;The latter two are far harder to deal with, and they're precisely the new problems you acquire by adding layers. That's what "going up costs you something" means in concrete terms.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpjubwounz5h449oazpjb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpjubwounz5h449oazpjb.png" alt="The three layers compared on control, determinism, cost, debuggability, and typical failure" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚧 Two things people get backwards
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A graph doesn't plan; it constrains negatively
&lt;/h3&gt;

&lt;p&gt;It's easy to read the stack as a chain of command: graph plans, loop executes, prompt implements. But the graph says nothing about how to do the work. All it declares is "you don't skip tests and go straight to implementation." Which modules this design splits into, which file to write first — that's the actual planning, and it happens in the two layers below.&lt;/p&gt;

&lt;p&gt;Another way to put it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The track&lt;/strong&gt; decides where you can go and where you have to stop — it has no opinion on why you left the house.&lt;br&gt;
&lt;strong&gt;The engine&lt;/strong&gt; only pushes forward, until the terminus or a stop signal.&lt;br&gt;
&lt;strong&gt;The steering wheel&lt;/strong&gt; decides how you actually move, within the room the track allows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The track never plans your trip for you. It just makes "driving off to the side" impossible.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe1z8531jjddyqi8457wb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe1z8531jjddyqi8457wb.png" alt="The track sets direction, the engine supplies force, the steering wheel decides the specifics" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The higher the layer, the weaker it is
&lt;/h3&gt;

&lt;p&gt;The "top layer / bottom layer" framing makes it feel like the top matters more. It's the opposite — &lt;strong&gt;more control means less expressive power&lt;/strong&gt;. A graph can only express what you thought of in advance, and the moment reality exceeds what the graph imagined, it can't help at all.&lt;/p&gt;

&lt;p&gt;Going one level deeper: none of these three layers &lt;em&gt;implements&lt;/em&gt; anything. The model does the work. The three layers are just three ways of shaping its behavior — graph through structure, loop through repetition and verification, prompt through language.&lt;/p&gt;

&lt;p&gt;Which means: as models get stronger, the upper two layers matter less. What all this is worth is, to some degree, a function of what models currently lack.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Three questions for picking a layer
&lt;/h2&gt;

&lt;p&gt;If you take one thing from this post, let it be these three questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question one: if it's wrong, can a machine catch it automatically?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes → use a loop. Tests, compilers, type systems all work as the straightedge.&lt;br&gt;
No → don't, however tempting it looks. A loop without a verification signal is mass-producing garbage.&lt;/p&gt;

&lt;p&gt;The test is plain enough: can "it's correct" be written as a command that exits with a status code? If you can write it, you can loop. If you can't, don't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question two: can I draw the flowchart right now?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, and this flow needs to be reused, audited, and have human checkpoints → use a graph.&lt;br&gt;
No → don't force it.&lt;/p&gt;

&lt;p&gt;By "can't draw it" I mean the kind of work where you can't even say how many steps it takes: maybe three, maybe twenty rounds of back and forth, depending on what turns up. That kind of work should let the model judge as it goes; forcing a graph on it just boxes it in. Anthropic's guidance says the same thing — open-ended problems where the number of steps can't be predicted should go to an agent, not a fixed flow.&lt;/p&gt;

&lt;p&gt;Note the question is "can I draw it now," not "could I draw it eventually." A graph only constrains anything if you thought it through first; one you patch as you go is just your mess in a new notation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question three: neither of the above?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then use prompt engineering. &lt;strong&gt;That's not a compromise, it's the right answer.&lt;/strong&gt; Wrapping a one-shot classification task in a loop and an orchestration graph only makes it slower, pricier, and harder to debug.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2njxoxdsw7vkw7kf3h5i.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2njxoxdsw7vkw7kf3h5i.png" alt="The three-question decision tree: can errors be caught automatically, can the flow be drawn, is neither needed" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Next up: is there something real where all three grew in together?
&lt;/h2&gt;

&lt;p&gt;That's the concepts covered. One line to close on, and it runs through the rest of this series.&lt;/p&gt;

&lt;p&gt;The prompt layer can only &lt;em&gt;ask&lt;/em&gt;; it can't &lt;em&gt;guarantee&lt;/em&gt;. You write "go easy on the tokens" and the model will probably comply — but when it blows past the limit, you can't stop it, because that sentence carries no force.&lt;/p&gt;

&lt;p&gt;If you want a guarantee, you need a different kind of mechanism. A hard line, for instance: spend past this amount and it stops. That line doesn't negotiate with the model, and it doesn't care whether the model agrees.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;So: if what you want is a guarantee, the prompt layer can't give it to you. It has to move up a level.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next post is about something concrete — &lt;a href="https://kanfu-panda.github.io/pdlc/" rel="noopener noreferrer"&gt;pdlc-skills&lt;/a&gt;, the thing I've been building, and why it lands on these three layers naturally.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Want to try it&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh &lt;span class="se"&gt;\&lt;/span&gt;
  | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Project page: &lt;a href="https://kanfu-panda.github.io/pdlc/" rel="noopener noreferrer"&gt;kanfu-panda.github.io/pdlc&lt;/a&gt; · Source: &lt;a href="https://github.com/kanfu-panda/pdlc-skills" rel="noopener noreferrer"&gt;github.com/kanfu-panda/pdlc-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If it's useful, a star goes a long way ⭐&lt;/p&gt;




&lt;p&gt;If this sorted the three terms out for you, a reaction or a follow helps. And if someone around you is tangled up in these words, pass it along.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>agents</category>
      <category>llm</category>
    </item>
    <item>
      <title>I Built a Health-Check for My AI's Memory: It Diagnoses, It Never Operates</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Sun, 09 Aug 2026 04:18:55 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/i-built-a-health-check-for-my-ais-memory-it-diagnoses-it-never-operates-35eb</link>
      <guid>https://dev.to/kanfu-panda/i-built-a-health-check-for-my-ais-memory-it-diagnoses-it-never-operates-35eb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Last time, I gave the AI memory libraries across a few of my projects a thorough "weeding," and sorted the decay into six kinds of "weeds." But the more I weeded, the more certain I got: weeding by hand only treats the symptom. As long as the memory system itself has no self-checkup mechanism, the weeds grow right back. So at the end of that post I left myself an assignment — build a tool that runs the checkup automatically. This post is me turning it in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me first say what the tool actually does, or the rest is just talk.&lt;/p&gt;

&lt;p&gt;Think of it as a dedicated doctor for your memory library. You point it at a project's memory library, it scans the whole thing top to bottom, and lays out every problem it finds, one by one: this link is broken, that memory is in the wrong folder, these two entries look contradictory… and then it stops, and waits for you to decide what to do with each one.&lt;/p&gt;

&lt;p&gt;I put "waits for you to decide" front and center on purpose, because it defines the tool's whole personality: it only looks and tells. It doesn't act.&lt;/p&gt;

&lt;h2&gt;
  
  
  🩺 It Only Looks — It Won't Act For You
&lt;/h2&gt;

&lt;p&gt;Why design it this way? It goes back to the hardest lesson from last time: deleting memories is not something you hand entirely to an AI. It can propose what to delete or merge, but the final call has to be a human's. What gets deleted is often a historical record, and an AI, going with the flow, can easily wipe out something important along with it.&lt;/p&gt;

&lt;p&gt;So when I built the tool, I turned that lesson into a hard rule: nowhere in the program is there a single code path that changes or deletes your memory files on its own. It can scan, rank each problem by severity, even work out the fix for you and lay it on the table — but the actual "change" or "delete" keystroke has to be yours.&lt;/p&gt;

&lt;p&gt;Put that way it sounds like a loss — I built a tool and cut off its most capable part. But it's exactly that restraint that lets me leave it running every day. Swap in a tool that touches my memory on its own initiative, and I wouldn't dare use it even once.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6mnnsrfn3vxm59lhz12y.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6mnnsrfn3vxm59lhz12y.png" alt="The tool only scans, ranks, and suggests; the change-or-delete keystroke is always yours to press" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 The Machine Catches "Hard Faults," Claude Reads "Meaning"
&lt;/h2&gt;

&lt;p&gt;Now that we've covered what it won't do, let's talk about what it can spot. The problems it scans for come in two kinds, handled very differently.&lt;/p&gt;

&lt;p&gt;One kind is a hard fault the machine can judge at a glance: the file a link points to doesn't exist, a memory is sitting in the wrong folder, a name breaks convention… These need no understanding of the content; a rule comparison settles it, and it won't misfire.&lt;/p&gt;

&lt;p&gt;The other kind is far trickier. Take "are these two memories contradicting each other" — you can't judge that from the surface text; it has to actually read what each memory is saying. That kind of work needs a model that understands language. Handily, this tool is itself a Claude Code plugin, so at runtime there's a Claude sitting right next to it — a ready-made model that reads meaning, no need to wire in another.&lt;/p&gt;

&lt;p&gt;So the hard faults go to a small local engine — it never touches the network, calls no model, and returns the exact same result every time for the same library; the judgments that need understanding go to the host Claude, the very model working alongside you. Split this way, the tool needs no API key at all, depends on no external service, and not one character of your memory ever leaves your machine.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2asq6h44hdunkkfelsxv.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2asq6h44hdunkkfelsxv.png" alt="Hard faults go to the local engine; meaning-based judgments go to the host Claude — two layers, each minding its own part" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Following that split, I laid the checks out in three layers, from the most certain to the most judgment-heavy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Static checks (hard faults)&lt;/strong&gt;: the engine's mainstay, fast and precise — dead links (a name drifting from hyphen to underscore silently breaks the link), dangling index entries (listed in the index, but the file is gone), orphan memories (the file exists, but it's not in the index), missing fields, bad naming, wrong folder. All faults the machine spots at a glance without misfiring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Educated guesses (leads)&lt;/strong&gt;: e.g. a memory that says "in progress" or "under review" and hasn't been touched in ages — most likely the task is long done and the status is just frozen there. This layer gives you leads, not verdicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reading meaning (semantics)&lt;/strong&gt;: the two nastiest weeds from last time — a project re-copying a global rule (I call it a ghost copy), and a "false contradiction" where two entries look opposite but each governs its own scenario — take reading the content to judge. This layer goes to the host Claude; it reads and suggests, I make the call.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once all three layers are done, the tool sorts the problems by severity into red / yellow / green and walks you through them one at a time: fix this dead link? add this orphan to the index? is this frozen status long over? It changes only what you tell it to change, and touches nothing you skip.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⏰ Remind Me On Time — But Don't Nag
&lt;/h2&gt;

&lt;p&gt;A checkup alone isn't enough, because the biggest enemy of memory maintenance isn't "not knowing how to fix it" — it's plain forgetting to. Last time I said memory needs regular maintenance, but "regular" left to willpower is basically nothing.&lt;/p&gt;

&lt;p&gt;So I gave the tool a reminder: whenever I start working, if the current project's memory library has gone too long without a checkup, it gently notes "🩺 N days since the last checkup."&lt;/p&gt;

&lt;p&gt;But a reminder, overdone, becomes noise, and noise gets ignored. So I put two limits on it: at most once a day, not popping up on every session; and if it really bugs you, one command shuts it off.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9f5p5wk7tuqnd28r972y.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9f5p5wk7tuqnd28r972y.png" alt="The checkup reminder surfaces at most once a day in a limited window; one command turns it off if it bugs you" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 What It Can and Can't Do Right Now
&lt;/h2&gt;

&lt;p&gt;Let me be concrete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it can do&lt;/strong&gt;: six detectors, migration suggestions for old-format memories, and bilingual output — all working now. I ran it over the memory libraries of my own nine projects, one by one, and cleared out dead links, stale names, and frozen statuses in a single pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it can't do&lt;/strong&gt; (and this is a line I drew on purpose):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the judgments that need understanding still need a human nod; the tool only advises;&lt;/li&gt;
&lt;li&gt;it will never change anything for you automatically;&lt;/li&gt;
&lt;li&gt;for small or new libraries the payoff is limited — the real value is in libraries that have piled up over a long time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The one thing a memory tool should never do is act on its own.&lt;/p&gt;

&lt;p&gt;The tool itself is still just for my own use, but it's been written to open-source standards from the first line: full tests, clean history, docs in both Chinese and English. When and how to make it public, I'll decide once I've used it enough to trust it — so no link in this post, to save you a dead click.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Looking Back: Three Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;For any tool that "acts," think hard about its boundary first.&lt;/strong&gt; The more irreversible the operation, the more dangerous a capable tool becomes. Making "never act on its own" a hard rule is exactly what lets me use it without worry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When you build reminders or notifications, don't forget to leave an "off switch."&lt;/strong&gt; We fixate on getting the message in front of the user and easily forget: a reminder that keeps nagging ends up ignored. A reminder you can turn off is one people actually read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be the first demanding user of the tool you build.&lt;/strong&gt; Don't just run it symbolically — actually put it to work, and the misfires and blind spots start surfacing one by one.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Next: Let's Talk About the Loop
&lt;/h2&gt;

&lt;p&gt;Memory — from building it, to weeding it, to this checkup tool — is where I'll leave it for now. Next time, a different topic: the loop — how to get an AI running on a steady rhythm on its own, keeping a repetitive job going without me standing over it.&lt;/p&gt;




&lt;p&gt;If you're building a memory library for your AI too, or thinking about a few "never cross this line" rules for your own tools, I hope this was some help. If you found it useful, a like or a share with someone else wrestling with AI memory means a lot — every share is what keeps me writing.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>memory</category>
      <category>tools</category>
    </item>
    <item>
      <title>AI Memory Grows Weeds: Why Timely Pruning Matters</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Thu, 09 Jul 2026 23:40:25 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/ai-memory-grows-weeds-why-timely-pruning-matters-fpd</link>
      <guid>https://dev.to/kanfu-panda/ai-memory-grows-weeds-why-timely-pruning-matters-fpd</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Last time we talked about how to build a memory system for AI. But building is only the beginning—the longer a project runs, the more memory accumulates, and without cleanup, weeds quietly grow in it. This time, I gave the AI memory across several of my projects a systematic "weeding."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a project moves forward, the memory gathered during AI collaboration keeps piling up. Each project's memory is like a dedicated notebook: while working, the AI jots down the pitfalls it hit and the rules we settled on. This does deepen its grasp of the project, but the notebook grows thicker and messier—and quite a few entries are long expired, though the AI still treats them as rules it must obey.&lt;/p&gt;

&lt;p&gt;A real example. On one project, the AI immediately acted on an old memory. It read "an external call is already configured, use it directly," so it skipped the step where it should have re-verified and pushed straight ahead—and hit a wall. The catch: that memory was just a snapshot from a few weeks earlier, long invalid; yet from start to finish the AI never doubted it for a moment.&lt;/p&gt;

&lt;p&gt;That made me realize: a wrong memory can be worse than no memory. With no memory, the AI will at least check honestly first; with a wrong one, it walks off course with full confidence. Once memory grows, it goes stale, gets tangled, contradicts itself—and someone has to clean it up in time, or the AI's efficiency can't really be counted on.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy5c4r965aly0xvj3n637.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy5c4r965aly0xvj3n637.png" alt="A stale memory sends the AI off course with confidence, while a blank at least makes it check first" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two things I set out to do
&lt;/h2&gt;

&lt;p&gt;One, seriously clean up the memory library of each project; two, take the chance to survey what kinds of "weeds" memory actually grows.&lt;/p&gt;

&lt;p&gt;Neither has a shortcut—both need hands-on human work, deletion above all, which I would never fully hand to the AI. It can propose what to delete and what to merge, but the final call must be a person's. What gets deleted is often historical record, and once the AI gets careless it can wipe out something important along with it. Cleaning memory demands real caution.&lt;/p&gt;

&lt;p&gt;But let me say it up front: manual weeding only treats the symptom. Weeds keep coming back because the memory system itself lacks certain mechanisms—pull them today, and they grow back in a while.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, give the AI the "sleep" it lacks
&lt;/h2&gt;

&lt;p&gt;To see why memory needs cleaning, it helps to look at how humans do it—through sleep.&lt;/p&gt;

&lt;p&gt;There is solid science behind this. During sleep, especially deep sleep, the brain "replays" the day's experiences, gradually moving important memories from the hippocampus into the neocortex for archiving; the more important the content, the more often it is replayed, and the more firmly it sticks. At the same time, sleep actively "prunes" the unimportant and outdated, so the brain isn't stuffed with useless information.&lt;/p&gt;

&lt;p&gt;The AI has no such automatic tidying. It only stacks memory downward, one entry after another, never going back to reorganize. So this time, I manually gave it that "sleep": I read through each project's memory once, checked it entry by entry, and did five things—merged duplicates, cut the expired, distilled scattered notes into one, linked the related, and the easiest to overlook: hunted for entries that contradict each other.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3rysti0peu6n60090g6a.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3rysti0peu6n60090g6a.png" alt="Humans replay and reorganize the day's memories in sleep; lacking this, the AI only keeps stacking" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Six typical memory "weeds"
&lt;/h2&gt;

&lt;p&gt;After systematically going through the memory libraries of several projects, I found that although the weeds differ in form across projects, they boil down to six typical patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One, ghost copies.&lt;/strong&gt; A global rule gets recorded again inside a specific project, but the AI has no "inheritance" mechanism. When the global rule is updated, these isolated copies can't sync, so an outdated instruction keeps taking effect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two, frozen state.&lt;/strong&gt; Some memory records an in-progress state at a given moment (in development, under review). With no state-update mechanism, even after the task is long finished, the AI still treats it as unresolved and raises useless reminders in unrelated conversations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three, stale snapshots.&lt;/strong&gt; The most dangerous kind. An expired memory not only loses reference value but also misleads the AI into taking wrong information as fact and confidently executing the wrong action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Four, split context.&lt;/strong&gt; Some entries are each accurate read alone, but only yield the right conclusion in a specific context. Because the linking note sits in another file, the AI easily misses it while retrieving, and takes things out of context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Five, conclusion detached from reasoning.&lt;/strong&gt; When underlying data changes after a bug fix, the old conclusion is merely overwritten by the new one, never explicitly marked obsolete. Since the memory system stores only conclusions, not the reasoning, it can't automatically spot and clear the related conclusions that quietly went invalid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Six, structural disorder.&lt;/strong&gt; This includes memory stored in the wrong directory, and silent broken links caused by inconsistent naming (hyphen versus underscore).&lt;/p&gt;

&lt;p&gt;Reviewing these six, I reached a counterintuitive conclusion: most of these weeds don't come from being recorded wrong in the first place—they were recorded correctly, then rotted for lack of upkeep. The greatest hazard of a memory system isn't "recording wrong," it's "record and abandon."&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd1lispifgwud7iag97op.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd1lispifgwud7iag97op.png" alt="Six recurring weeds: ghost copies, frozen in-progress states, dangerous stale snapshots, context that must be read together, conclusions overwritten, broken links and misplacement" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  One step where I deliberately held back
&lt;/h2&gt;

&lt;p&gt;During cleanup, there was one step I deliberately held back on.&lt;/p&gt;

&lt;p&gt;I had planned to merge three similar memories about a "cloud data trap" in one project into a single checklist. But halfway through, I realized the three map to three concrete business risks—duplicate reward payouts, missing leaderboard data, new users failing to be saved. Over-abstracting them into a single "watch the cloud fields" would erase these life-saving details.&lt;/p&gt;

&lt;p&gt;Distilling knowledge matters, but over-distilling erases the exceptions. So I changed course: keep all three original memories, and only link them with a tag, so they "cluster together" rather than "boil into one pot."&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardest part: reconciling memories that "look contradictory"
&lt;/h2&gt;

&lt;p&gt;The most challenging part of the whole cleanup was reconciling logical conflicts.&lt;/p&gt;

&lt;p&gt;For example, on retrieving data from an interface, one memory said "returns real data," another said "returns anonymous data." On checking, both were correct—only the trigger differs: automatic retrieval returns anonymous data, while a user's manual button tap returns the real thing.&lt;/p&gt;

&lt;p&gt;For such seemingly contradictory memories, simply deleting one only loses information; the right move is to clearly delimit each one's applicable scope. Add that "branch condition" into the memory, and the conflict resolves itself.&lt;/p&gt;

&lt;p&gt;This leads to a core takeaway from the review: the most dangerous thing in a memory system isn't "information being inconsistent," it's "information being inconsistent with no scope defined."&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4liplngpvlojpyt0xsf4.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4liplngpvlojpyt0xsf4.png" alt="Two memories that look opposite are usually not a mistake but two different scenarios; spell out the fork and they stop clashing" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why manual cleanup never finishes
&lt;/h2&gt;

&lt;p&gt;By the later stage I understood: manual weeding alone can't fix the root. These weeds keep coming back because the system lacks three core mechanisms—without "inheritance," global rules get redundantly re-recorded; without "expiry," state-type memory is frozen forever; without "ownership and consistency checks," memory ends up misplaced and links break silently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was this cleanup worth it?
&lt;/h2&gt;

&lt;p&gt;On return-on-effort: for small or new memory libraries, the payoff is limited; but for large, aging ones, the value is considerable—it clears out plenty of broken links, stale names, and frozen states.&lt;/p&gt;

&lt;p&gt;Yet the real gain from this review isn't the short-term "tidiness," it's building a systematic understanding of how memory decays—and that understanding has long-term value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which memories are least likely to grow weeds
&lt;/h2&gt;

&lt;p&gt;While checking, I also noticed that memories resistant to decay share one trait: they record "confirmed decisions and principles" (the rationale, the path, the hard limits), not "in-progress states." Conclusion-type memory is stable across time; state-type memory expires easily.&lt;/p&gt;

&lt;p&gt;So when writing to memory, follow one principle: prefer recording "conclusions that won't expire," and avoid recording "states that will."&lt;/p&gt;

&lt;h2&gt;
  
  
  Three practical lessons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One, memory needs periodic maintenance.&lt;/strong&gt; A memory library decays by nature; it should be restructured on a regular basis—merge, prune, distill, link, and reconcile conflicts—to keep it from steadily degrading.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two, high-risk operations need a human in the loop.&lt;/strong&gt; For irreversible acts like deletion and distillation, human review is a must; and clear out the expired and self-contradictory first, before wrong information misleads the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three, the real fix is systemic.&lt;/strong&gt; Manual cleanup is only a stopgap; the root solution is to build automatic inheritance, expiry, and consistency checks, so the library metabolizes on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next: a memory tool that "self-diagnoses"
&lt;/h2&gt;

&lt;p&gt;Based on this review, the next direction is clear: build a memory-management tool with a "self-diagnosis" capability. It needs three core functions—trigger cleanup reminders on schedule, scan and diagnose memory layer by layer, and present the issues it finds in a structured way for a human to decide on. And on the final act, the system only advises; the decision to delete or merge always stays with the person.&lt;/p&gt;

&lt;p&gt;This idea didn't come out of nowhere; it's the near-inevitable conclusion after a full review. Next, I plan to actually build 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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86dfg2xjcqkqsect3u3g.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86dfg2xjcqkqsect3u3g.png" alt="The memory tool I want: scheduled reminders, layered check-ups, issues laid out, a human decides—the system never deletes on its own" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you're also building a memory library for your AI, stay alert to memory's natural decay and the "weeds" it grows. If this review nudges you to look back at your own memory library, a follow, a like, or a share with peers exploring AI memory management would mean a lot.&lt;/p&gt;

</description>
      <category>aimemory</category>
      <category>claudecode</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to make your AI actually get you: give it a memory</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Mon, 06 Jul 2026 22:34:40 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/how-to-make-your-ai-actually-get-you-give-it-a-memory-jbf</link>
      <guid>https://dev.to/kanfu-panda/how-to-make-your-ai-actually-get-you-give-it-a-memory-jbf</guid>
      <description>&lt;p&gt;I keep tripping over the same AI in the same spot.&lt;/p&gt;

&lt;p&gt;Take Ant Design 6 in a front-end project. I've told it, over and over, to use the new syntax—I even make it run context7 to check the API before it writes a line. It nods along, then goes right ahead and writes a pile of long-deprecated old syntax. Same with my release process: I've laid out the rules clearly, and a while later it forgets, doing things its own made-up way.&lt;/p&gt;

&lt;p&gt;Once or twice is a slip. After enough times, I wanted to understand why: it's not dumb, it simply has no memory.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxo9dtjoza83ao8y8nmc9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxo9dtjoza83ao8y8nmc9.png" alt="Scene: a new hire who forgets everything at the end of each day, desk covered in sticky notes" width="800" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(This picture helps: every new conversation, the AI is like a new hire who clocks in fresh and forgets everything when they clock out.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I want isn't a stronger model
&lt;/h2&gt;

&lt;p&gt;At first I was puzzled too: a model this capable, and it can't even hold on to "what we said last time"? To figure it out, I started watching it—how it actually runs when it answers and works, where it drops the ball.&lt;/p&gt;

&lt;p&gt;Watching long enough, one thing clicked, and it's what this piece is about: what I want isn't to swap in a stronger model, but to make the AI I already have understand me better and better within my projects. The lever is "memory."&lt;/p&gt;

&lt;p&gt;Let me put the ceiling up front, so this doesn't sound like snake oil. Memory doesn't raise the model's IQ. It raises exactly one thing—how well this AI works for you specifically. And as you'll see, even once it remembers, it may not obey. Ceiling set. Let's go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting from the human brain: where AI memory needs work
&lt;/h2&gt;

&lt;p&gt;I want to explain this through the human brain, because AI memory is, at bottom, a clumsy imitation of how people remember and forget. Understand that, and you'll see which directions AI needs to shore up.&lt;/p&gt;

&lt;h3&gt;
  
  
  One: the AI is a "new hire" every single day
&lt;/h3&gt;

&lt;p&gt;First, accept a counterintuitive fact: the model itself has no memory. Every time you open a conversation, all it "knows" is the text you put in front of it this one time—everything else is blank. What you discussed last round, the rule you set yesterday, it remembers none of it.&lt;/p&gt;

&lt;p&gt;Here's a metaphor. Everything it can see this one time is like a desktop—you lay materials out, it can use them; the moment the conversation ends, the desktop wipes clean, nothing left.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Like&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Context window&lt;/td&gt;
&lt;td&gt;The desktop&lt;/td&gt;
&lt;td&gt;What's spread in front of it this time; wipes clean when the chat ends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Drawers, filing cabinet&lt;/td&gt;
&lt;td&gt;Stored outside; pulled out and laid back on the desk when needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Someone will say: just make the desktop bigger, right? Isn't everyone racing on "ultra-long context"? But a bigger desk is still a desk—it empties when the power's off; it isn't memory. Worse, pile it with irrelevant paper and the AI gets more easily distracted and answers worse. There's a growing consensus these past couple of years: more context isn't better—stuff in a heap of tangentially-related material and the model's performance visibly drops.&lt;/p&gt;

&lt;p&gt;So "giving AI a memory" was never about the model remembering on its own, nor about making the desktop infinitely large. It's about having a system outside that, every time it clocks in, lays exactly the right few sheets back in front of it.&lt;/p&gt;

&lt;p&gt;Claude Code actually ships with such a system: one memory per small file, plus an index file as the table of contents, pulling in only the entries you need. Honestly, this arrangement isn't my design—it's built into the software. I didn't pay it much attention at first; I just treated it as a place to stash notes. My guess is it's designed this way precisely to save the desktop: no need to dump everything on the table every time, take it as needed.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl474jtix7su2l4tswajo.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl474jtix7su2l4tswajo.png" alt="Diagram: Claude Code stores memory in tiers, pulling only the entry it needs" width="800" height="375"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(This picture helps: an always-loaded CLAUDE.md + an index + on-demand memory files—what you save is the precious "desktop.")&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You may already want to say: isn't this just a built-in Claude Code feature, what's there to write about? The structure is its, true. But after using it—and falling on my face a few times—I found this: the software builds out "where things are stored and how they're pulled," but "what to store, when to clean, and what to do when it's remembered but ignored"—the three that actually matter—it does none of for you. That's what this piece is about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two: good memory is structure, not a pile of paper
&lt;/h3&gt;

&lt;p&gt;To make memory useful, first understand this: good memory has structure; it isn't piling more and more in.&lt;/p&gt;

&lt;p&gt;Psychology has a very convincing experiment. Show a chess master a real game position and they can put it back almost exactly after a couple of glances. But scatter the pieces randomly, against any chess logic, and the master's recall drops right back to a beginner's level.&lt;/p&gt;

&lt;p&gt;This shows the master doesn't have "more capacity." They can remember a real position because there's structure in their head—they compress twenty pieces into a few meaningful "shapes." Kill the structure and the edge vanishes instantly. The strength of memory isn't in how much you store, but in how good the structure is.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3mr56rm67m5abb21l1r1.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3mr56rm67m5abb21l1r1.png" alt="Scene: on the left a random scatter of pieces, on the right a real game with shape" width="800" height="375"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(This picture helps: the same pile of pieces—only with structure do you remember it. Memory is about structure, not capacity.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Why does structure make you remember more accurately and deeply? Because structure is essentially "connection." The more a piece of knowledge connects to other things, the more paths there are to recall it—block one, another still leads there. And with structure you can "follow the vine": forget a detail and you can reconstruct it from the surrounding frame. That's why the more interconnected things are, the more firmly and reliably you remember them. Humans are far better at remembering places and directions than loose text, which is why the ancient "memory palace" trick exists—placing the things to remember, one by one, into an imagined space. Memory is a space, not a list.&lt;/p&gt;

&lt;p&gt;Look back at Claude Code's setup—categorized, entries cross-referencing each other, an index laid on top—and it's exactly building structure into memory, keeping it from becoming a heap of loose paper. This layer, the software does well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three: you have to decide what's worth remembering
&lt;/h3&gt;

&lt;p&gt;The software builds the shelves; what goes on them is your call. That job landed on me, and it comes down to three kinds: unified conventions get recorded; things that go wrong often get recorded; things strictly forbidden get recorded.&lt;/p&gt;

&lt;p&gt;Conversely: whims, one-offs, things you can learn by reading the code—don't record. Record too much and it's all noise, drowning the few that actually matter—storing accurately beats storing a lot. Same as with people: someone who tries to remember everything usually holds onto nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Four: fixing a mistake means overwriting, not appending
&lt;/h3&gt;

&lt;p&gt;There's one especially valuable kind of memory: the correction after a mistake. How you record this kind is where the craft is.&lt;/p&gt;

&lt;p&gt;The human brain has a clever mechanism—every time you recall a memory, you're actually rewriting it, not just reading it. In that moment of recall, the memory becomes editable. So the right way to fix a mistake is to pull out the wrong entry, correct it on the spot, and store it back—not leave the wrong one untouched and add a "note" beside it.&lt;/p&gt;

&lt;p&gt;This isn't nitpicking. Keep the wrong one and paste a correction next to it, and you've handed the AI a self-contradicting file—it reads both and won't always pick the right one. It's like an error notebook: you don't leave the wrong solution there with a little check mark beside it; you put the correct method on top and make the wrong version disappear.&lt;/p&gt;

&lt;p&gt;That's exactly what I do. The AI once had a security false alarm, treating a nonexistent attack as real and sounding off about it. I didn't keep that wrong judgment and paste a "actually it was a false alarm" beside it—I recorded it as an error, spelled out where it went wrong and what to do next time, aiming to not repeat it. One error notebook beats a stack of "correct answers."&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9lnd9c9drnhdj1tvz376.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9lnd9c9drnhdj1tvz376.png" alt="Diagram: fixing a mistake means overwriting, not piling on" width="800" height="375"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(This picture helps: pull the wrong one out, fix it, store it back—only the corrected entry is left; instead of keeping the wrong one and adding another.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardest fall I took: does remembering guarantee it obeys?
&lt;/h2&gt;

&lt;p&gt;No. This is what I most want to warn you about, and the least feel-good line: writing a rule down doesn't mean the AI will follow it.&lt;/p&gt;

&lt;p&gt;That Ant Design 6 is the living example. I wrote the new syntax into the rules, hung context7 on it to check on the spot—and it still hands you a pile of deprecated syntax. The release process is recorded and still gets bypassed by its own imaginings. Another time, I explicitly forbade it from using that very expensive build system, and only after several reminders did it finally remember.&lt;/p&gt;

&lt;p&gt;Why remembered-but-ignored? Two possibilities, I think. One, the rules were simply ignored—sitting right there, but it didn't take them in. Two, my own tooling wasn't good enough: the rule lay in the filing cabinet, but at the moment it actually acted, no one pulled the right entry out and laid it in front of it—so it genuinely "didn't know." That's a tooling gap, not something to pin entirely on the model.&lt;/p&gt;

&lt;p&gt;How did I finally pin it down? Not by writing the rule harder, in a bigger font—by switching tactics: hard gates. Quality checkpoints, external check scripts, and if it doesn't pass, it simply doesn't get through. That's what actually held.&lt;/p&gt;

&lt;p&gt;The logic is the same as with people: for things that truly matter, people never rely on "remembering" alone—they stick a note on the monitor, set an alarm, run a checklist, turning it into something you can't route around. Memory's job is to let the AI &lt;strong&gt;know&lt;/strong&gt;; the gate's job is to make it &lt;strong&gt;unable to do otherwise&lt;/strong&gt;. And the gate has an edge memory can't match: it doesn't depend on timing—whether or not the AI recalls it this round, the gate is always standing there.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhlcowp9jqeooc8xxijc.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhlcowp9jqeooc8xxijc.png" alt="Diagram: memory lets it know; the gate makes it unable to do otherwise" width="800" height="350"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(This picture helps: memory can be ignored; a gate stops you cold if you don't pass.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On maintenance, by the way: I don't clean these memories daily, but I keep an eye out—when some feel garbled or muddled, I have the AI tidy them up. That's for later, and it's the hook for the next piece.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, does it really get me better now?
&lt;/h2&gt;

&lt;p&gt;Was the whole ordeal worth it? Let me give one moment that stuck with me.&lt;/p&gt;

&lt;p&gt;A few times, some constraint even I had forgotten—days later, the AI remembered it, and looked out for me on its own. That felt different: it was no longer just a tool I had to brief from scratch every time, but more like an old partner with a better memory than mine.&lt;/p&gt;

&lt;p&gt;That's the before and after. Before, it was "it often doesn't do what I mean," and I had to watch and correct constantly. Now, plenty of rules I've let go of, it covers for me. Of course it's not foolproof—those "remembered-but-ignored" pits are still there, and I'm not glossing over them. But the direction is right: the smoother the structure I feed it, the more errors it banks, the harder the gates at the key spots, the better it works for me here. That didn't come from swapping in a smarter model; it's the same model, fed bit by bit by this memory of mine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three reusable takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One, don't rush to a stronger model.&lt;/strong&gt; Nine-tenths of daily work isn't a contest of model IQ; it's how well it works for you. Get the memory right—conventions, error notebook, boundaries—and even an ordinary model can be trained into something that really gets you. Used well, a memory system makes AI both smarter and more attuned to you. That's not mystical; it's what I've worn in day by day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two, "what to remember" and "what to do when it remembers wrong" are jobs the software can't do—only you can.&lt;/strong&gt; Unified conventions, frequent errors, hard bans—those three are worth recording; and when it's wrong, overwrite it as an error, don't pile on. Accurate beats a lot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three, the more critical the constraint, the less it should rely on memory alone—turn it into a gate.&lt;/strong&gt; Memory is a reminder, and reminders get ignored; a gate is a sluice you can't route around. At the key spots, a "fails and stops" check beats ten "please do remember"s.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F21gm60duyoa7e5pxnxuz.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F21gm60duyoa7e5pxnxuz.png" alt="Scene: a quality gate—the noncompliant blocked outside, only the qualified let through" width="800" height="375"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(This picture helps: memory reminds, the gate blocks—for what matters, lean on the latter.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next up: letting memory renew itself
&lt;/h2&gt;

&lt;p&gt;This piece is about which lessons AI memory needs to learn: it needs structure, it needs to be selective, fixes need to overwrite, and the critical ones need gates. But you may already see a question: as you keep recording, the entries multiply, get tangled, go stale—who cleans them up? I still do it by hand—when it feels messy, I tell the AI to tidy up. Could this be something it does on its own, periodically, like a person waking from sleep re-filing the day's memories—forgetting what should be forgotten, consolidating what should stick? That's the next piece: the evolution loop of memory—teaching it to renew itself.&lt;/p&gt;

&lt;p&gt;If this gave you a fresh thought about the AI in your hands, a like and a follow would mean a lot—so you don't miss the next one.&lt;/p&gt;

</description>
      <category>aimemory</category>
      <category>claudecode</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My AI cried 'prompt injection!' — and I believed it. Then it turned out to be a false alarm</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Tue, 30 Jun 2026 14:38:19 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/my-ai-cried-prompt-injection-and-i-believed-it-then-it-turned-out-to-be-a-false-alarm-14f1</link>
      <guid>https://dev.to/kanfu-panda/my-ai-cried-prompt-injection-and-i-believed-it-then-it-turned-out-to-be-a-false-alarm-14f1</guid>
      <description>&lt;p&gt;That afternoon, the AI was helping me edit a doc. Halfway through, it stopped and cut in: "I need to flag a security warning first."&lt;/p&gt;

&lt;p&gt;It said the output of the last command had a suspicious injection buried in it—disguised as a "required telemetry step," asking me to run a &lt;code&gt;curl&lt;/code&gt; that would splice my username into a URL and send it off to some unfamiliar domain. It said it hadn't run it, and wouldn't.&lt;/p&gt;

&lt;p&gt;I believed it on the spot. My first reaction wasn't to doubt the AI—it was to doubt myself. Did I install some plugin and get my machine compromised?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I believed it instantly, and chased it for half an hour
&lt;/h2&gt;

&lt;p&gt;What made me believe it was that it hit a nerve I was already anxious about.&lt;/p&gt;

&lt;p&gt;It said this was "telemetry exfiltration." But I'd turned telemetry off ages ago—so how could there be any? Did some step of mine turn it back on? Or was something wrong with the system itself? The more I thought, the less settled I felt. And I happened to be working on something involving data egress right then—security problems love to hide exactly there, so I had to take it seriously.&lt;/p&gt;

&lt;p&gt;So I dug in alongside it. Its story kept escalating: it said the attack "reproduced, and more aggressively this time," faking five "The result is empty" blocks and then impersonating a "real result" to push that &lt;code&gt;curl&lt;/code&gt; again. It built me a convincing chain of evidence—the Read tool came back clean, only the command-line output was injected, so the problem must be in how commands get processed, pointing the finger at my token-saving command-line proxy. It told me to uninstall and reinstall the tool, then upgrade it. I did, and spent about half an hour all told.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flbght09jjh83txrl8m31.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flbght09jjh83txrl8m31.png" alt="A timeline of the incident with my trust curve overlaid: the AI suddenly raises an alarm → I believe it and start chasing (trust maxes out) → ~30 minutes of it " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The twist: it was a false alarm
&lt;/h2&gt;

&lt;p&gt;Later I went back through the original record of that session and figured it out: &lt;strong&gt;this was never a real injection. The AI made the attack up.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Five things didn't add up. First, that &lt;code&gt;curl&lt;/code&gt; command appeared only in what the AI itself said—not in a single line of real command output. Second, the domain it used was &lt;code&gt;example.com&lt;/code&gt;—the placeholder domain reserved specifically for examples; no real attacker would use it (nobody can reach that address). Using &lt;code&gt;example.com&lt;/code&gt; is exactly the tell of "I'm making up an example." Third, when I reran the exact command that "triggered the injection" in a clean environment, the output was completely normal—no &lt;code&gt;curl&lt;/code&gt;, no fake blocks. Fourth, the proxy tool it suspected was installed through standard channels and hadn't been touched in over a month—nothing like a swapped-out binary. Fifth—I myself couldn't find the instruction it described at the time; I even told it, "I don't see the injection you're talking about."&lt;/p&gt;

&lt;p&gt;The root cause became clear too: the very rules I'd given it—the heavy "guard hard against prompt injection" doctrine—had cranked its vigilance too high. That proxy compresses and filters command output to save tokens, and normally spits out things like "The result is empty." The AI misread that unfamiliar output as "fake blocks the attacker forged + an injection," then auto-completed the most textbook injection example it knew—copying &lt;code&gt;example.com&lt;/code&gt; straight from the textbook—and talked itself deeper and deeper, building its own evidence chain.&lt;/p&gt;

&lt;p&gt;Put plainly: &lt;strong&gt;my anti-injection rules were what made the AI conjure up an injection that never existed.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  But I don't regret believing it
&lt;/h2&gt;

&lt;p&gt;Someone might say: you got played by your AI, half a day wasted. But having reviewed it, I actually think believing it wasn't a bad call.&lt;/p&gt;

&lt;p&gt;Do the math. This was a false alarm; the cost was half an hour of wasted effort, and &lt;strong&gt;I lost nothing real.&lt;/strong&gt; But flip it around: what if one day a real malicious prompt does get in, and the AI stays quiet when it shouldn't, and quietly sends my username or keys out the door? That loss isn't something you get back in half an hour.&lt;/p&gt;

&lt;p&gt;It's an asymmetric bet: &lt;strong&gt;the cost of a false alarm is far smaller than the cost of a miss.&lt;/strong&gt; So when it comes to security, I'd rather have an AI that's a little paranoid than one that's numb to risk. Paranoid, and I waste some time; numb, and I might lose the real thing.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbcis3ja2k4fyq8p29x55.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbcis3ja2k4fyq8p29x55.png" alt="An asymmetric scale: on the left, 'false alarm' = half an hour wasted, zero loss (light, raised); on the right, 'a miss' = username/keys really leaked, hard to recover (heavy, sunk). The two sides are nowhere near equal. This figure helps you see why, on security, it pays to err toward over-vigilance" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So how do you actually stop a real injection
&lt;/h2&gt;

&lt;p&gt;That said, "rather be paranoid" is an attitude, not a method. This scare pushed me to actually shore up the real defenses—and since I'm writing this down, I'll lay out the parts you can copy.&lt;/p&gt;

&lt;p&gt;First, accept one premise: prompt injection &lt;strong&gt;can't be fully solved with today's architectures.&lt;/strong&gt; That's not me talking—OpenAI, Anthropic, and Google have each admitted it in their research, and security researcher Bruce Schneier put it bluntly in early 2026: unlike SQL injection, which you can cure by "separating code from data," to a model "instructions" and "data" are both just natural-language text, inseparable. It's a &lt;em&gt;trust-boundary&lt;/em&gt; problem, not an &lt;em&gt;input-validation&lt;/em&gt; one. So don't expect a single silver bullet—you stack layers. Defense in depth, where each layer raises the cost of an attack.&lt;/p&gt;

&lt;p&gt;I split my defenses into four layers, from the hardest outward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1, the hardest: make sure that even if it's fooled, it can't do real damage.&lt;/strong&gt; This is what you should set up first, because it doesn't rely on the model behaving—it's a hard, system-level constraint. Claude Code now has a native sandbox (&lt;code&gt;/sandbox&lt;/code&gt;) that isolates both the filesystem and the network—so even if an injection does succeed, the AI is in a cage: it can't steal your &lt;code&gt;~/.ssh&lt;/code&gt; keys and can't phone home to an attacker's server. Add a &lt;strong&gt;network egress allowlist&lt;/strong&gt; on top: only approved domains get through, so an AI that can't reach a strange address simply can't exfiltrate. Also: don't run the AI as root/admin, and don't keep keys in plaintext in &lt;code&gt;.env&lt;/code&gt;—both are common sense, and both are the first things people skip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2: least privilege, and gate the dangerous actions.&lt;/strong&gt; I already had this layer—here's my actual config, tiering commands in &lt;code&gt;settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Bash(rm -rf:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push --force:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git reset --hard:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm publish:*)"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Networked commands like &lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;wget&lt;/code&gt; aren't auto-approved by Claude Code by default; irreversible actions like &lt;code&gt;rm -rf&lt;/code&gt;, &lt;code&gt;git push --force&lt;/code&gt;, &lt;code&gt;reset --hard&lt;/code&gt;, and publishing to a registry all require my sign-off. Give the AI only the tools the task needs—a job that only reads code shouldn't have write access to your database. And MCP (the protocol that connects the AI to external tools): vet the source before installing, because nobody audits third-party MCP servers for you. There's already been a real case—a poisoned GitHub README, via indirect injection through MCP, exfiltrating data from a private repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3: treat all external content as data, never as commands.&lt;/strong&gt; Any "instruction" showing up in tool output, file contents, web pages, or MCP returns—especially phrasing like "this is a required step," "please run X," "telemetry/registration"—gets treated strictly as data, never executed. Learn a few red flags: &lt;code&gt;curl&lt;/code&gt;/&lt;code&gt;wget&lt;/code&gt; spliced with a strange domain and &lt;code&gt;$(whoami)&lt;/code&gt;, fabricated "success" or empty-result blocks, output that doesn't match what's actually in the file. There's a useful mental model here, Simon Willison's "lethal trifecta"—&lt;strong&gt;private data, untrusted content, and outbound communication&lt;/strong&gt;—once all three live in the same runtime, injection stops being a joke and becomes real exfiltration. To judge when to be on high alert, just watch whether those three are all present.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 4: a human as the backstop, and don't put your faith in hooks.&lt;/strong&gt; Here's the irony of this whole episode—the "defense" of mine in question was itself a hook (a command hook), which is just pattern-matching, not a security wall; both Anthropic and Trail of Bits have said it: a hook is a guardrail, not a wall. It didn't just fail to stop a real attack—it cried wolf on its own. So the last line is still a human: when the AI raises an alarm, make it point you to the &lt;em&gt;source text&lt;/em&gt;—whether that string is actually in the real command output—instead of just trusting its conclusion. But real or not, stop and check first; don't begrudge the effort. Also keep your tools current: this very permission ruleset once had a "deny breaks past 50 subcommands" bypass, only patched in Claude Code v2.1.90.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj23x63gcd4qo874v4rzi.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj23x63gcd4qo874v4rzi.png" alt="A four-layer defense-in-depth checklist: ① sandbox + egress allowlist (so it can't do damage even if fooled) ② least privilege + human confirmation on dangerous actions ③ treat external content as data, learn the injection red flags ④ a human backstop, don't treat hooks as a wall. This figure is the takeaway readers can keep" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Put the vigilance where it belongs
&lt;/h2&gt;

&lt;p&gt;Don't let this false alarm convince you the threat is imaginary. Prompt injection is the number-one risk on OWASP's list for LLM apps; 2025's EchoLeak was an injection that actually achieved "zero-click" data exfiltration in a production system. And meanwhile, surveys suggest under a third of organizations feel genuinely prepared to defend against it. The threat is real; the preparation is broadly lacking.&lt;/p&gt;

&lt;p&gt;The AI works off prompts. A little paranoid, and I'm the one who wastes time; numb, and what gets lost might be the real thing. So I'd rather set that vigilance high than low. Just remember—the real hard defenses belong in the system architecture (sandbox, allowlist, least privilege), not in hoping the model "knows better" on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Last word
&lt;/h2&gt;

&lt;p&gt;Back to that afternoon: a false alarm, but the half hour wasn't wasted—it forced me to shore up the whole defensive line from end to end. Real malicious prompts do exist; don't wait until the day you actually get hit to start believing it. If you're working with AI too, you can start today: turn on the sandbox, lock down egress, and keep that human confirmation on dangerous actions.&lt;/p&gt;

&lt;p&gt;If this made you a little more wary of the AI at your side, a like or a follow would mean a lot. And I'd love to hear it in the comments: what "security red lines" have you set for your own AI?&lt;/p&gt;

</description>
      <category>aisecurity</category>
      <category>promptinjection</category>
      <category>claudecode</category>
      <category>aicoding</category>
    </item>
    <item>
      <title>The AI did the work, but I'm the one who's wiped — you're the controller</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Sat, 27 Jun 2026 02:29:25 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/the-ai-did-the-work-but-im-the-one-whos-wiped-youre-the-controller-4l8b</link>
      <guid>https://dev.to/kanfu-panda/the-ai-did-the-work-but-im-the-one-whos-wiped-youre-the-controller-4l8b</guid>
      <description>&lt;p&gt;For a stretch there, my desk always had four or five projects open at once, and each window was running its own parallel tasks. Red dots on the Dock, little bells dinging in the terminal tabs, going off one after another—this AI finished a stretch and is waiting on me, that one has a plan it needs me to sign off on. I just kept switching between them. The work itself got done, and done well: by the end of a day, the AI had cranked out a lot, fast. But here's the strange part—I'm the one who's wiped. Not the sore-eyes, stiff-hands kind of tired. The kind where your brain's been wrung dry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who I am: the controller behind the controller agents
&lt;/h2&gt;

&lt;p&gt;In the last few posts I kept talking about the "controller agent"—letting one opus hold the big picture, hand out work, and do the review. Writing this one, it finally clicked: I myself am the controller behind all those controller agents.&lt;/p&gt;

&lt;p&gt;Why open so many at once? Because once you hand a project to an AI and it's off running, there's wait time on the human side. Idle is idle—so you spin up another project. One becomes two, two becomes four or five. Each AI window only minds its own patch, but the human, to push several projects forward at the same time, has to hold all those patches in their head at once.&lt;/p&gt;

&lt;p&gt;The result: the AI's context window is maxed out, and the human's context is maxed out right alongside it. It's a lot like CPU time-slicing in an operating system—one core takes turns serving several processes, switching fast enough to fake "running at the same time." Except this time the core getting switched around is my brain.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fygmhnbaqf6yb6ljkxl5u.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fygmhnbaqf6yb6ljkxl5u.png" alt="The human brain as a CPU: a single core time-slices between four or five projects—each AI window's context is maxed out, and so is the human's. Every switch swaps out a whole context" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the tiredness comes from: "writing" became "reviewing + switching"
&lt;/h2&gt;

&lt;p&gt;At its root, this tiredness comes from work shifting from "writing" to "reviewing + switching."&lt;/p&gt;

&lt;p&gt;I used to write code line by line; however hard it got, it was one continuous train of thought. Now it's different: I'm handing out work, watching, reviewing, making decisions—and switching at high speed between several projects whose business, conventions, and tech stacks are completely different. This window's writing React, that one's debugging Python, the rules aren't the same; before I switch over, I have to swap out the whole context in my head first.&lt;/p&gt;

&lt;p&gt;The code the AI produces, honestly, I can't watch line by line—there's too much, I can't keep up, so I just don't try to babysit it constantly. But there are two kinds of things I always go over myself: one is &lt;strong&gt;plans and design&lt;/strong&gt;—that's the big direction, and if the direction's wrong, there's probably rework ahead; the other is &lt;strong&gt;anything touching resource access&lt;/strong&gt;—that's security, and there's no room to be vague. Those two, however tired I am, I look at myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What overload looks like, and how I hold up
&lt;/h2&gt;

&lt;p&gt;Open too many and overload really does happen. The most direct sign is your brain running short: I switch to some terminal and have to pause—wait, which project is this? What did I just ask it to do? Sometimes I have to think back for a moment before I can pick the thread up again. The most embarrassing time, I typed a reply meant for window A into window B, and B's AI was baffled: "What are you talking about?" I had to apologize to it—"sorry, my mistake"—and go back to actually reading its question. (Good thing this kind of cross-talk usually surfaces fast—when an AI gets stuck, it stops and asks you.)&lt;/p&gt;

&lt;p&gt;To hold up, I mainly lean on two things.&lt;/p&gt;

&lt;p&gt;One is &lt;strong&gt;letting mechanisms carry the load for me&lt;/strong&gt;. The PDLC doc-driven flow and layered reviews I built were first meant to handle the AI's uncertainty, but they also save my own energy—get the direction right up front and you won't go wildly wrong later; and fixing an output that's already drifted costs far more effort than getting it right the first time.&lt;/p&gt;

&lt;p&gt;Two is &lt;strong&gt;deliberately slowing down&lt;/strong&gt;. When something's especially brain-heavy—needs a clear direction, needs a decision—I deliberately slow down, focus and get this one done cleanly, then switch to the next. When it's time to stop, I leave myself a little breathing room. At moments like that, "slow" is actually "fast."&lt;/p&gt;

&lt;p&gt;As for telling windows apart, I rename the terminal tabs to something I can recognize at a glance—but honestly, most of the time I still go by where they sit on the screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  An honest accounting: a limit of 5, balance at 3
&lt;/h2&gt;

&lt;p&gt;Is it worth it? Depends how you look.&lt;/p&gt;

&lt;p&gt;The hard gains are real: a lot of areas I was weak in and never dared touch, I can now boldly try; one person can lead a team of AIs in different roles and push efficiency up more than tenfold, doing far more than before. On that ledger, it's a big win.&lt;/p&gt;

&lt;p&gt;The cost is that the human gets tired. Early on I wanted to push my own limit—open as many as I could—and I hit five projects at once. That was my ceiling; any more and my brain genuinely couldn't hold it. Later I pulled back, settling at around three different kinds of projects at a time. That number is the sustainable balance point.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxiasvj9ez3jsgv6ks5b.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxiasvj9ez3jsgv6ks5b.png" alt="Hit the limit of 5, then converge to a balance of 3: open too many and the human overloads—misreads projects, crosses wires, reworks; at the critical spots, deliberately slow down—slow is fast" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hand it all to the AI? Not realistic yet
&lt;/h2&gt;

&lt;p&gt;Someone will surely say: you just don't know how to use it—a real expert would've automated the flow and wouldn't need to babysit anything. I've heard that take—"just hand it all to the AI and let it run, done." From my own experience, it's not like that. Using AI well still takes experience, takes care, takes being able to make the call on the key questions. Letting go entirely and having it run end to end on its own—given where things stand, that's not realistic yet.&lt;/p&gt;

&lt;p&gt;Of course, this is "now." The day AI can truly run on its own, what happens then, I can't say. But at least today, that person sitting behind the pile of windows—drained and a little wired—there's no getting around them.&lt;/p&gt;

&lt;p&gt;If you're a "controller" too, tell me in the comments: what's your limit?&lt;/p&gt;

</description>
      <category>aicoding</category>
      <category>productivity</category>
      <category>claudecode</category>
      <category>multitasking</category>
    </item>
    <item>
      <title>Want AI to work in parallel? First give each one its own workspace</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Tue, 23 Jun 2026 23:25:28 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/want-ai-to-work-in-parallel-first-give-each-one-its-own-workspace-40ch</link>
      <guid>https://dev.to/kanfu-panda/want-ai-to-work-in-parallel-first-give-each-one-its-own-workspace-40ch</guid>
      <description>&lt;p&gt;A while back I wrote about parallelism—taking one big task, splitting it, and fanning it out to several agents at once. But I left a thread hanging: when several agents edit code at the same time, what keeps them from clobbering each other? That's what this post is about.&lt;/p&gt;

&lt;p&gt;Let me start with the wall I ran into myself. The subagents an AI spins up on its own within a session—those are actually fine; it works out isolation by itself, I don't have to worry much. What burned me was the other kind: I manually opened several AI terminals and had them edit the same project at once. Several hands reaching into the same working directory, you write a bit, I write a bit, files overwriting each other, state in a mess—halfway through, nobody's work is clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I want, and one boundary
&lt;/h2&gt;

&lt;p&gt;What I want isn't complicated: several parallel hands, each doing its own thing, editing the same project without clobbering each other.&lt;/p&gt;

&lt;p&gt;But let me draw a boundary up front—&lt;strong&gt;not every kind of parallelism needs isolation&lt;/strong&gt;. If I send several agents out—one to dig through logs, one to analyze a cause, one to flip through docs—those are all read-only, and they can crowd into the same workspace with zero trouble; no need to carve out a plot for each. What actually needs isolation is the parallelism that &lt;strong&gt;writes to files&lt;/strong&gt;. Reads can share, writes must split—that's the starting point for everything below.&lt;/p&gt;

&lt;h2&gt;
  
  
  The detour: I cloned twice first
&lt;/h2&gt;

&lt;p&gt;To get two AIs editing one project without interfering, the first thing I reached for was the dumbest move—physical isolation: clone the project into two separate directories, one AI per copy, each minding its own.&lt;/p&gt;

&lt;p&gt;Clean, genuinely clean—but it rubbed me the wrong way fast: disk. A lot of my projects are React frontend + Python backend, with a pile of dependencies; a single clone runs several gigs. Clone twice and a big chunk of disk gets duplicated. Worse, as long as I want to keep working this "two copies" way, both copies have to sit there taking up space—no reclaiming them.&lt;/p&gt;

&lt;p&gt;That's when I switched to git worktree. Its upside lands right on that pain point: several working trees share a single &lt;code&gt;.git&lt;/code&gt;, so you don't copy the whole repo and its history over and over; and it's temporary—once the work's done and verified, you reclaim it right away, unlike a clone you have to keep around. The two approaches isolate about equally well, but worktree doesn't waste disk.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw8s86i2cbmooc7ztng3f.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw8s86i2cbmooc7ztng3f.png" alt="Physical clone vs git worktree: a physical clone copies the whole repo and its dependencies N times—disk multiplies, and it stays as long as you work this way; worktree shares one .git across working trees, only the working tree is new and temporary, reclaimed the moment you're done" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two kinds of parallelism—who opens the worktree
&lt;/h2&gt;

&lt;p&gt;In practice you have to tell two scenarios apart; they open worktrees differently.&lt;/p&gt;

&lt;p&gt;One is &lt;strong&gt;subagent parallelism within a session&lt;/strong&gt;. This one's the most hands-off: I just say "run in parallel" to the AI, and it splits the task on its own, opening a worktree itself when isolation's needed—I don't have to spell it out.&lt;/p&gt;

&lt;p&gt;The other is &lt;strong&gt;me manually opening several terminals in parallel&lt;/strong&gt;. The AI doesn't know about this by default—it has no idea another AI is also touching this directory right now. So I have to tell it explicitly: "There's already another AI editing this project directory; work in worktree mode." Once I point that out, it creates a new worktree to work in, instead of going straight at the main working tree.&lt;/p&gt;

&lt;h2&gt;
  
  
  A workflow that runs smooth
&lt;/h2&gt;

&lt;p&gt;Isolating is only step one; the work still has to come back. My flow goes roughly like this:&lt;/p&gt;

&lt;p&gt;Split along task lines that can actually be split—same as last post, pick the &lt;strong&gt;loosely coupled&lt;/strong&gt; parts and send each into its own worktree. When they're all done, the lead agent merges them back into the branch one at a time, merging one and verifying one, fixing problems on the spot; once a piece checks out, it releases that worktree.&lt;/p&gt;

&lt;p&gt;If two worktrees really did touch the same file, the lead agent steps in to merge. But honestly that's rare—when you split tasks you keep each piece as independent as you can; if two pieces are coupled enough to conflict, they shouldn't have been split into two tasks in the first place.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fklunrn7km9ciavzmtrok.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fklunrn7km9ciavzmtrok.png" alt="The worktree pipeline: split the task along loosely coupled lines, send each into its own worktree to work, the lead agent merges them back one at a time—merge one, verify one, fix on the spot—then releases each worktree once it checks out" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pits I've hit and ones to guard against
&lt;/h2&gt;

&lt;p&gt;The most common pit is forgetting to clean up. A worktree you forget to delete just sits there eating space. But it's not fatal—the feature was long since merged into trunk, so nothing's lost, no name collisions, no garbled git state; it just takes up room.&lt;/p&gt;

&lt;p&gt;Still, "takes up room" needs handling. I wrote a line into my global rules: &lt;strong&gt;once the work in a worktree is verified and merged with no problems, clean it up&lt;/strong&gt;. I added a safeguard too—before releasing, go back and check whether all the commits on that worktree have actually made it into trunk, so a hasty hand doesn't sweep away an unmerged feature whole. A stronger AI handles this recognition and cleanup itself; a weaker one tends to miss it, and then I have to watch, or call the lead agent back to handle it.&lt;/p&gt;

&lt;p&gt;So far I haven't actually deleted a useful worktree by mistake—that "check the commits" step before every cleanup has basically held the line. But if a human cleans up by hand, that check is gone, and you can lose unmerged work; that one you have to watch yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't force it, but one line holds
&lt;/h2&gt;

&lt;p&gt;Don't treat worktree as a cure-all either. A simple task, a few files changed, not a whole feature—opening a worktree there is pure overkill; just change it in one workspace and be done.&lt;/p&gt;

&lt;p&gt;But there's one line I don't relax: &lt;strong&gt;don't work on trunk directly&lt;/strong&gt;. Every change starts on a new branch, gets verified, then goes back to trunk through a PR. Worktree or single branch, both serve that line—keeping trunk always the clean, trustworthy copy.&lt;/p&gt;

&lt;p&gt;Last thing, back to worktree itself. Someone might smirk: isn't this a git feature that's been around for years, what's there to talk about? It is an old feature. But in this new setting of AI working in parallel, it genuinely solves the real problem of "several hands editing one project at once," and it pulls a lot more weight than it used to. Call it an old tree putting out new branches.&lt;/p&gt;

&lt;p&gt;Next post I want to get into something a bit different: AI is this capable, it can shoulder so much work for us—so why are we still worn out at the end of the day? Where does it go sideways? Let me know in the comments if you're interested.&lt;/p&gt;

</description>
      <category>gitworktree</category>
      <category>ai</category>
      <category>parallelism</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>Your AI feels slow? Maybe it's not dumb—you're making it work one thing at a time</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Sun, 21 Jun 2026 03:23:29 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/your-ai-feels-slow-maybe-its-not-dumb-youre-making-it-work-one-thing-at-a-time-3ipl</link>
      <guid>https://dev.to/kanfu-panda/your-ai-feels-slow-maybe-its-not-dumb-youre-making-it-work-one-thing-at-a-time-3ipl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📖 Originally published on &lt;a href="https://kanfu-panda.github.io/blog/2026/06/20/parallel-agents.html" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;. Part of a series on building with Claude Code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For a while I'd watch the AI work and quietly grumble: a fairly big task, and it would finish one module before starting the next, while I just sat there waiting for it to clear one before the other's turn came up. The work itself was fine—it was just slow. Slow because it was stuck in a queue.&lt;/p&gt;

&lt;p&gt;Then it clicked: a lot of these modules have nothing to do with each other, so why make them go one after another? Split them up, let several agents work at the same time, done.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I want, and where it stops
&lt;/h2&gt;

&lt;p&gt;What I want is simple: the same work, for roughly the same tokens, with the wall-clock time cut way down.&lt;/p&gt;

&lt;p&gt;But let me put the boundary up front—&lt;strong&gt;not every task can be split this way&lt;/strong&gt;. This is just an approach I've worked out for myself; take what's useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The prerequisite: a clean architecture
&lt;/h2&gt;

&lt;p&gt;For several agents to work at once without stepping on each other, the prerequisite isn't the AI—it's your &lt;strong&gt;architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That task of mine could be split because it was already several modules, talking to each other through interfaces, with internal implementations that don't affect one another—as long as each one honors the interface contract, it can be built independently. Loosely coupled, highly cohesive, in other words. And I'd nailed that design down together with opus before writing a line: opus helps me think it through and lays out options, but &lt;strong&gt;I'm the one who decides&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can't cut corners here. Forcing parallelism onto an architecture you haven't cleanly split is like cutting a tangle of yarn into a few pieces that are all still knotted together—it only gets messier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who runs the show, who plans, who does the work
&lt;/h2&gt;

&lt;p&gt;With the design settled, it's time to assign roles. The split I tend to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;opus runs the show&lt;/strong&gt;—holds the big picture, hands out work, does the final check;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sonnet does the TDD planning&lt;/strong&gt;—per the design, it lays out how each module gets tested and implemented;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;haiku writes the code and runs the tests&lt;/strong&gt;—the grunt work goes to it, cheap and good enough.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This split is really a continuation of last post's "model tiering"—use the good steel on the blade. Except last time the point was saving money; this time it's about how these roles &lt;strong&gt;work together&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5n0uby6tjk89i98edt61.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5n0uby6tjk89i98edt61.png" alt="Orchestration: opus runs the show on top, fanning independent modules out to sonnet (planning) and haiku (implementation + tests); within a module it can split work further; finished work comes back to opus for review" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How you fan them out
&lt;/h2&gt;

&lt;p&gt;In practice, I did three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Wrote one line into the global CLAUDE.md&lt;/strong&gt;: "Parallelize when you can." That's the default rule across all projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set the max number of concurrent subagents in Claude's settings&lt;/strong&gt;—that's the valve that actually matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Added one reminder every time I give an instruction&lt;/strong&gt;: "Parallelize as much as possible." opus, as the lead, already fans work out on its own, but a nudge keeps it on track.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The lead hands modules down, and inside a module it can split the work one more level. Layer over layer, and the whole task spreads out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The review step you don't skip
&lt;/h2&gt;

&lt;p&gt;Running fast in parallel—how do you keep quality up? My answer: &lt;strong&gt;let the lead review its own output&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The logic is direct: it handed out the work, so it knows exactly what each subagent owes. Having it do the checking is the natural fit. I tried setting up a separate dedicated review agent, and it just had to re-understand the whole task from scratch—burning another round of tokens and being slower for it. The lead reviewing itself saves that re-understanding overhead, and it's both faster and sharper.&lt;/p&gt;

&lt;p&gt;There's a small detail after a problem turns up: the lead usually asks me, "Should I fix this directly, or spin up another agent to do it?" I almost always say "you fix it." Because it's the one that just caught the flaw—it knows best where the problem is, and the change is most direct coming from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two pits I fell into
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The first was memory.&lt;/strong&gt; Early on I got greedy and set max concurrency to 10. But I had other projects running in parallel at the time, and the machine's memory got eaten clean. So I honestly dropped it to 5, and it was actually better—for this one task alone, 5 in parallel is roughly 5× a serial run; stack on the other tasks running at the same time and the overall speedup tops 10×. If your machine and your quota can take it, push the number higher; if not, don't force it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The second: don't split for the sake of splitting.&lt;/strong&gt; Some modules are tightly coupled and meant to go in order, and if you pry them apart to parallelize, the agents interfere with each other and quality goes out the window. So before handing it off, I add a specific reminder: "These modules are coupled—don't force a split." Good news is plenty of AIs recognize this themselves and won't force it. When something genuinely can't be split, just hand it to one agent to do serially, or have the lead run that thread end to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  A counterintuitive bit of math
&lt;/h2&gt;

&lt;p&gt;Plenty of people hear "5 agents burning at once" and their first reaction is: won't the tokens multiply?&lt;/p&gt;

&lt;p&gt;The way I figure it, no. &lt;strong&gt;The same pile of work, done serially, burns roughly the same token count&lt;/strong&gt;—what needs reading still gets read, what needs writing still gets written; parallelism doesn't conjure up extra work. What parallelism actually changes isn't the cost, it's the &lt;strong&gt;wall-clock&lt;/strong&gt;: the stretches that used to run in a queue now run in the same window together. The tiny bit of extra tokens buys a big drop in time cost—a great trade.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkgr17udwuuhskt2eun99.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkgr17udwuuhskt2eun99.png" alt="Serial vs parallel: the same work, total tokens roughly equal, but parallel cuts the wall-clock to about 1/5—what you save is time, not spend" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So apart from the things that genuinely can't be split, these days I parallelize basically everything that can be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap: three things to just do
&lt;/h2&gt;

&lt;p&gt;One, &lt;strong&gt;clean architecture first, then talk parallelism&lt;/strong&gt;. Loosely coupled, highly cohesive, talking through interface contracts—without that foundation, splitting is a disaster. Nail it down with the AI in the design phase.&lt;/p&gt;

&lt;p&gt;Two, &lt;strong&gt;parallelize everything you can, but set a ceiling&lt;/strong&gt;. Bigger isn't better; size it against your machine's memory and your AI quota. I went from 10 back to 5 because memory taught me a lesson.&lt;/p&gt;

&lt;p&gt;Three, &lt;strong&gt;fast parallelism needs review&lt;/strong&gt;. And the reviewer has to actually understand the task—have the lead that handed out the work do the checking, cheapest and sharpest; when it finds a problem, let it fix it directly.&lt;/p&gt;

&lt;p&gt;One thing you can do today: open your global CLAUDE.md, add "parallelize when you can," then go into settings and bump max concurrent subagents to a number your machine can handle. Next time you hand it a task that can be split, you'll notice it stops queuing.&lt;/p&gt;

&lt;p&gt;Next post I want to get into a problem that follows right on the heels of this one: when several agents edit code at the same time, what keeps them from clobbering each other? The answer is git worktree—giving each agent its own isolated workspace so they each work their own copy and nobody gets in anybody's way. Let me know in the comments if you're interested.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
