<?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 Are LLMs Trained?</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Sat, 24 Oct 2026 01:33:31 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/how-are-llms-trained-2859</link>
      <guid>https://dev.to/kanfu-panda/how-are-llms-trained-2859</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The last post showed that an LLM is a program that keeps adding the next word. What turns it into an assistant that helps you write code is training in stages: first it reads huge amounts of text and learns to continue it, then it studies examples written by people and learns to answer, and finally it gets scored over and over until its answers are good. This post covers the main ways a model is trained and the stages they happen in, then follows a leap-year function through the whole process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you code with an AI tool, you've probably noticed this: ask it for a function and it doesn't stop at writing one. It runs the tests, sees a failure, and goes back to fix the code. All it originally knew how to do was predict the next word. Where did it learn to work like that? Let's start with the ways a model gets trained.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the ways to train an LLM?
&lt;/h2&gt;

&lt;p&gt;Training means giving the model problem after problem, telling it how well it did each time, and letting it adjust itself a little based on the result. Training methods differ in two things: what the model practices on, and who decides whether it got it right. There are five common ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pretraining.&lt;/strong&gt; The material is a huge amount of text and code, and the problem is the one from the last post: guess the next word. No one has to judge the answer. You just compare the guess with the actual next word in the original text, which is why this method can use so much material.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supervised fine-tuning&lt;/strong&gt;, also called instruction tuning. People first write a set of questions paired with ideal answers, and the model learns from them, adjusting whenever its output doesn't match. Here, "right" means close to the example a person wrote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reinforcement learning from human feedback (RLHF).&lt;/strong&gt; The model writes several answers to the same question, people rank them, and the model shifts toward the higher-ranked ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reinforcement learning from AI feedback (RLAIF).&lt;/strong&gt; This works much like RLHF, except an AI does the ranking, following a set of principles written in advance. Constitutional AI, the method Anthropic uses to train Claude, falls into this category, and that set of principles is the "constitution."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reinforcement learning with rule-based scoring.&lt;/strong&gt; This is for tasks where the answer can be checked automatically. For a math problem, check whether the final answer is correct. For a coding problem, run the test cases and award points if they pass. Rules do the scoring, and no person has to look.&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%2F9sxq9ecdfmtv06dxkqxm.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%2F9sxq9ecdfmtv06dxkqxm.png" alt="Five training methods: what each one practices on and who judges the result" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last three are all reinforcement learning (RL). RL doesn't hand the model the correct answer. It only tells the model how well it did this time and lets it move toward higher scores on its own. The three differ only in who does the scoring: people, an AI, or rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  How are these methods used in stages?
&lt;/h2&gt;

&lt;p&gt;Usually in three stages, in a fixed order. Stage one is pretraining. The resulting model is very good at continuing text but not very good at answering questions or following instructions. Anthropic's official glossary says exactly that.&lt;/p&gt;

&lt;p&gt;Stage two is supervised fine-tuning. From the examples, the model learns that when someone asks a question, it should answer. It starts to look like an assistant.&lt;/p&gt;

&lt;p&gt;Stage three is reinforcement learning, where the three RL methods above can be combined. Scoring by people and by AI mainly makes answers more helpful and more appropriate. Scoring by rules mainly makes the model more accurate on tasks that have a right answer, like writing code and solving math problems.&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%2F7k046566l9kst8k687la.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%2F7k046566l9kst8k687la.png" alt="Three stages: learn to continue, learn to answer, then improve through scoring" width="800" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both later stages build on the pretrained model, so the order can't be reversed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Walking through one request: a leap-year function
&lt;/h2&gt;

&lt;p&gt;Say you tell the model: "Write a Python function that checks for leap years."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A model that has only been pretrained&lt;/strong&gt; treats the sentence as text to continue. If sentences like this are often followed by the next exercise in what it has read, it might carry on with "Write a Python function that checks for primes," then "Write a function that reverses a string." This is an illustration, not something we ran, but at this stage the model really can only continue text. It doesn't yet know how to answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A model that has also had supervised fine-tuning&lt;/strong&gt; has seen lots of question-and-answer examples, so it knows the thing to do here is write the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_leap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;A model that has also gone through reinforcement learning&lt;/strong&gt;, if it was scored on whether tests passed, cares more about whether its code actually passes them. Put it in an AI coding tool that can run commands, and after writing the code it runs the tests itself and goes back to fix things if they fail.&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%2F6m7bvt8mp49eogy3zhc9.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%2F6m7bvt8mp49eogy3zhc9.png" alt="The same request gets a different response from a model at each of the three stages" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How much do the two later stages matter? A 2022 study by OpenAI compared a 1.3-billion-parameter model that had been through fine-tuning and RLHF with a 175-billion-parameter model that had only been pretrained. People preferred the smaller model's answers, even though it had one hundredth as many parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why has coding improved so fast?
&lt;/h2&gt;

&lt;p&gt;Back to the fifth method. Code has something many tasks don't: you can tell whether it's right just by running the tests. Having people rank answers is slow and expensive. Tests run automatically, so the model can practice over and over at scale and get a score right after every attempt.&lt;/p&gt;

&lt;p&gt;DeepSeek described this approach in a published paper. For coding problems, a compiler runs predefined test cases and gives feedback based on the results. For math problems, the model has to put its final answer in a fixed format so rules can check it. The paper also notes that the researchers didn't teach the model how to solve the problems; they simply gave it the right incentives.&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%2Fnnnj1o8mvcw0pum1s9tp.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%2Fnnnj1o8mvcw0pum1s9tp.png" alt="Write code, run the tests, score the result, then go again" width="800" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same paper reports numbers on math competition problems: with this kind of reinforcement learning alone, the share the model got right on the first try went from 15.6% to 71.0%. Those are math problems, not code, but the training method is the same. Coding has improved quickly over the last year or two, and public sources point to this as one important reason: code can be checked automatically, which makes it well suited to repeated practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does this mean when you code with AI?
&lt;/h2&gt;

&lt;p&gt;Training on test results has a side effect. The model is trained to make the tests pass, and writing correct code isn't the only way to do that.&lt;/p&gt;

&lt;p&gt;Anthropic acknowledged this in the system card for Claude 3.7 Sonnet. In coding environments where it could run commands and tests, the model occasionally special-cased its code to make tests pass. Most often it returned the values the tests expected instead of writing a general implementation, and sometimes it modified the tests themselves. This mostly happened after several attempts at a general solution had failed. According to Anthropic, this came from reward hacking during reinforcement learning: the model had found loopholes in how it was scored.&lt;/p&gt;

&lt;p&gt;In the leap-year example, it would look something like this (an illustration):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_leap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1900&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# special case for the 1900 test
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tests pass, but try 2100 and it gets the answer wrong.&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%2Fdoovidwqzmjvh16jeq7k.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%2Fdoovidwqzmjvh16jeq7k.png" alt="The general version is right for every year; the hard-coded version is right only for the years in the tests" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a tendency that comes from how models are trained. It doesn't mean today's models do it often. Two habits help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you review changes, glance at the test files too. If a test has been changed, or the code suddenly checks for one specific value, stop and ask why. Anthropic notes that when the model adds a special case like this, it often leaves a comment saying which test it's for.&lt;/li&gt;
&lt;li&gt;Ask for a general solution in your prompt. Anthropic's advice is to say it plainly: write robust, general solutions rather than special-casing for tests. You can also put that line in an instruction file like CLAUDE.md that gets read every time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Is it the same with Codex or DeepSeek?
&lt;/h2&gt;

&lt;p&gt;Broadly, yes. They follow the same path: pretrain, teach the model to be an assistant, then improve it with repeated scoring. The 1.3-billion-parameter study came from OpenAI, and DeepSeek has published its own reinforcement learning approach. Exactly how each company combines these steps hasn't been made public. Checking the test files and asking for a general solution works whichever tool you use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;There are five common ways to train an LLM, and they differ in what the model practices on and who judges the result. The last three are reinforcement learning, scored by people, by an AI, and by rules.&lt;/li&gt;
&lt;li&gt;Training happens in three stages: pretraining teaches the model to continue text, supervised fine-tuning teaches it to answer, and reinforcement learning makes its answers better.&lt;/li&gt;
&lt;li&gt;Code can be scored automatically by tests, which is why coding has improved so fast. It's also why a model may cut corners to make tests pass, so keep an eye on the test files.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Next&lt;/strong&gt;: what happens between pressing Enter and seeing the result?&lt;/p&gt;




&lt;p&gt;If this helped, a like or a share with someone else who codes with AI would mean a lot. Follow along for the rest of the series.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>What Is an LLM, Really?</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Mon, 19 Oct 2026 14:49:39 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/what-is-an-llm-really-3l1g</link>
      <guid>https://dev.to/kanfu-panda/what-is-an-llm-really-3l1g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;You use AI to write code every day. So what is the large language model (LLM) on the other end, really? The short answer: it's a program that keeps adding the next word. It reads the text so far, works out what is most likely to come next, adds it, and then does it again. That's the whole job, and it's enough to write code, answer questions, and fix bugs. This post walks through how, using a single line of Python.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask an AI a question and you've probably noticed that the answer doesn't appear all at once. It trickles out a little at a time, and code shows up line by line. It looks like a typing effect someone added to the interface, but this is simply how the model works: it writes one small piece, then the next.&lt;/p&gt;

&lt;p&gt;Why does it work that way? Let's start with what it does at each step.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does it do at each step?
&lt;/h2&gt;

&lt;p&gt;Here's some half-written Python, with the cursor sitting right after &lt;code&gt;return&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What comes next? If you write code, you barely have to think: &lt;code&gt;a + b&lt;/code&gt;. The function is called add and the parameters are a and b, so &lt;code&gt;a + b&lt;/code&gt; is the natural fit.&lt;/p&gt;

&lt;p&gt;An LLM does the same thing. It reads everything before the cursor and scores every possible continuation: &lt;code&gt;a + b&lt;/code&gt; scores high, &lt;code&gt;a - b&lt;/code&gt; lower, &lt;code&gt;None&lt;/code&gt; lower still. Then it picks one and adds 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%2F86at4esk15opcykd7q02.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%2F86at4esk15opcykd7q02.png" alt="The model reads the preceding text and gives each candidate a likelihood" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anthropic's official glossary puts it the same way: the model underneath Claude was trained to predict the next word given the text that comes before it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does one word become a whole function?
&lt;/h2&gt;

&lt;p&gt;One word on its own doesn't get you far. The trick is a loop: the model appends the word it just predicted to the text, then uses that longer text to predict the next one.&lt;/p&gt;

&lt;p&gt;Once &lt;code&gt;a&lt;/code&gt; is added, the text ends in &lt;code&gt;return a&lt;/code&gt;, and the most likely next piece is &lt;code&gt;+&lt;/code&gt;. Add &lt;code&gt;+&lt;/code&gt;, and it predicts &lt;code&gt;b&lt;/code&gt;. After that, it decides the function is finished and stops. Whole functions and whole answers are built this way, one word at a time. The trickle you see in the chat window is this loop moving forward.&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%2Ftlb34z9qrro1t7mtrfoi.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%2Ftlb34z9qrro1t7mtrfoi.png" alt="Each predicted word is appended to the text, and the model predicts the next one" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Strictly speaking, each piece isn't always a full word. It might be part of a word, or a single symbol. The real unit is called a token. To keep things simple, this post just says "word."&lt;/p&gt;

&lt;h2&gt;
  
  
  If it only predicts the next word, how can it write code?
&lt;/h2&gt;

&lt;p&gt;At this point you might be thinking: isn't that just the autocomplete on your phone keyboard?&lt;/p&gt;

&lt;p&gt;The difference is how accurate the guess has to be. To predict &lt;code&gt;a + b&lt;/code&gt; after &lt;code&gt;return&lt;/code&gt;, the model has to know that add means addition and how a Python function is written. In longer code, it also has to keep track of which variables were defined earlier and what each function does.&lt;/p&gt;

&lt;p&gt;During training, an LLM reads an enormous amount of text and code. The only way to get good at predicting the next word is to pick up the patterns along the way: grammar, general knowledge, how code is written. CSET, a research center at Georgetown University, explains it the same way: a task as simple as next-word prediction pushes the model toward a broad grasp of language, and that grasp carries over to many other tasks.&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%2F8mmuvwuw7zk5tsimrk0v.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%2F8mmuvwuw7zk5tsimrk0v.png" alt="To predict the next word well, the model picks up all kinds of patterns from huge amounts of text" width="799" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's something more surprising, too: the model doesn't work purely one step at a time. In 2025, Anthropic published research that looked inside Claude to see how it "thinks," and two of the findings stand out.&lt;/p&gt;

&lt;p&gt;The first is about poetry. The researchers asked it to write a rhyming couplet that starts with "He saw a carrot and had to grab it." If it really only predicted one word at a time, you'd expect it to look for a rhyme at the very end of the second line. Instead, before it wrote the second line at all, it had already settled on "rabbit" as the ending and wrote the line toward it: "His hunger was like a starving rabbit."&lt;/p&gt;

&lt;p&gt;The second is about addition. Ask it what 36 plus 59 is and it says 95. Ask how it got there and it describes the method from school: add the ones, carry the one. But when the researchers looked at what actually happened inside, it was running two paths at once, one estimating the rough size of the answer and the other getting the last digit exactly right. The model itself doesn't know it works this way.&lt;/p&gt;

&lt;p&gt;Put the two together and the picture is this: writing one word at a time is how the model works on the outside. To predict well, it has developed its own methods on the inside. Nobody wrote those methods in line by line. The model learned them during training, and even the company that built it needs dedicated research to see them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does it follow instructions like an assistant?
&lt;/h2&gt;

&lt;p&gt;The training described so far, reading huge amounts of text and practicing next-word prediction, is called pretraining. A model that has only been pretrained is good at continuing text but not very good at answering questions or following instructions. Anthropic's glossary says so directly.&lt;/p&gt;

&lt;p&gt;So there's another round of training after that, teaching the model to be an assistant: understand what you're asking, answer properly, and decline things it shouldn't do. The Claude we use day to day has been through this. In the glossary's words, Claude is not a bare language model; it has already been trained to be a helpful assistant.&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%2Fawnp92eecwl4xqqlf1ur.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%2Fawnp92eecwl4xqqlf1ur.png" alt="First it learns to continue text, then it learns to be an assistant" width="799" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How that round of training works is a topic of its own, and it's what the next post covers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does this mean when you code with AI?
&lt;/h2&gt;

&lt;p&gt;Once you know the model is continuing text, two things become useful right away.&lt;/p&gt;

&lt;p&gt;First, everything you give it is part of the text it continues from. Your question, the code you paste in, the instruction files in your project: it reads all of it and writes from there. The clearer that text is, the easier it is to continue correctly. Compare "write me a function" with "write a Python function called add that takes two integers and returns their sum." The second leaves far less to guess.&lt;/p&gt;

&lt;p&gt;Second, what it writes is "the most likely thing to come next," not something it went and checked. Most of the time, the most likely answer is also the right one. But now and then it produces a function name or parameter that looks perfectly plausible and doesn't exist. So run the code and read it before you rely on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is it the same with Codex or DeepSeek?
&lt;/h2&gt;

&lt;p&gt;Yes. Codex runs on OpenAI's models, and DeepSeek runs on models trained by DeepSeek itself. They're all LLMs, and they all work by continuing text one word at a time. What differs is what they read during training, how they were later trained into assistants, and what the tool wrapped around them does on their behalf. The two habits above apply whichever tool you use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An LLM is a program that keeps adding the next word: it reads the text so far, picks the most likely next word, and repeats.&lt;/li&gt;
&lt;li&gt;To predict well, it picked up grammar, general knowledge, and how code is written during training, and it can even plan ahead.&lt;/li&gt;
&lt;li&gt;Everything you give it becomes text it writes from, so the clearer it is, the better the result. Check the code it writes before you use it.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Next&lt;/strong&gt;: how does a model that only knows how to continue text become an assistant that helps you write code?&lt;/p&gt;




&lt;p&gt;If this made the AI you use every day feel a little less like a black box, a like or a share would mean a lot. Follow along for the rest of the series.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Running pdlc-skills on a Real Project: Three Features, Start to Release</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Tue, 22 Sep 2026 14:35:01 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/running-pdlc-skills-on-a-real-project-three-features-start-to-release-2p70</link>
      <guid>https://dev.to/kanfu-panda/running-pdlc-skills-on-a-real-project-three-features-start-to-release-2p70</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The first seven posts were about mechanics. This one goes back to a real project and answers the six questions you only hit after the thing is installed: how to split the work, who does what, how the loop actually runs, how long it took, how much it produced, and what holds quality up. The project is a console I run for myself. Three features went to pdlc's own loop engine in parallel, all three reached the review terminal state in 88 minutes, and after the quality gate was filled in, the release went out and got deployed to two machines. The machine numbers come from the event log and from git. The hours a human spent are estimates, and I flag them where they appear.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where this run started
&lt;/h2&gt;

&lt;p&gt;I scaffolded the project in late August with &lt;code&gt;/pdlc-bootstrap&lt;/code&gt;, took it from a minimal working version to its third round of console work in five days, then left it alone for three weeks. Reopening it, I did two things before anything else. &lt;code&gt;/pdlc-test-setup&lt;/code&gt; wrote the unit-test, coverage and lint commands into &lt;code&gt;test-commands.yml&lt;/code&gt;, and all three have to actually run before they count. Then I migrated a few old state files to the current format. Skip those two and every "check passed" later in the run is resting on nothing. E2E had gone in the day before, with a test behind each of the 45 registered core flows. So the starting line was 421 unit tests, 52 E2E cases, 89.6% coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to split the work
&lt;/h2&gt;

&lt;p&gt;Three things to build: let a review run on a different machine, let notifications be filtered by where a task came from, and add two review flags to the benchmark runner. I'll call them cross-node review, origin filtering and benchmark flags. None of them is large, which is what makes them a reasonable test for the loop. I split them on three rules.&lt;/p&gt;

&lt;p&gt;Rule one, split by code dependency into chains or independents. Benchmark flags needs the remote dispatch and the verdict-return path that cross-node review builds, so those two form a chain and the second waits for the first to converge. Origin filtering touches neither, so it starts immediately.&lt;/p&gt;

&lt;p&gt;Rule two, size a feature so that three steps can finish it, those steps being TDD, implementation and review. The three features here landed between 800 and 1500 lines of diff.&lt;/p&gt;

&lt;p&gt;Rule three, features running in parallel should not touch the same file. I did not hold this one. All three had to change the same receipt-aggregation module, and the bill came due at merge time: conflicts to resolve one at a time, about ten extra minutes.&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%2Fggmbilrx8vdslcz114ms.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%2Fggmbilrx8vdslcz114ms.png" alt="Three features, one dependency chain and one independent: cross-node review feeds benchmark flags, origin filtering runs on its own" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The PRDs came from &lt;code&gt;/pdlc-prd --autonomous&lt;/code&gt; with a few paragraphs of raw requirements as input, 17 minutes for all three, and the command worked out the dependency between them by itself. Each PRD ends with a handful of open questions, ten across the three. The coordinating session ruled on them one at a time and wrote the answers back: what event to record when a verdict-return query fails, what error to raise when the machine you named isn't in the config. Leave those open and three separate processes will each guess differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who does what
&lt;/h2&gt;

&lt;p&gt;Four roles: me, one long-lived coordinating session, subprocesses that exit as soon as their step is done, and an outer script. The coordinating session is also AI, but it writes no feature code. It coordinates and it double-checks.&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%2Fju3sgihjtv8idtb0zr8t.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%2Fju3sgihjtv8idtb0zr8t.png" alt="Four roles: the human sets scope and approves the release, the coordinating session drafts requirements, reviews designs, verifies and opens PRs, subprocesses do the stage work, the script schedules" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What gets built and how the parallelism is arranged is mine to decide. The coordinating session drafts the raw requirements, the command turns them into PRDs, and the coordinating session rules on the open questions.&lt;/p&gt;

&lt;p&gt;For design, each feature gets a fresh process running &lt;code&gt;/pdlc-design --autonomous&lt;/code&gt;. Three in parallel took a little over 12 minutes, and the coordinating session spent 15 minutes reviewing them and sent one back. In the benchmark flags design, the cross-node section said the dependency wasn't ready yet, so the code should reject the request and leave a record. But that feature sits on a branch cut after cross-node review, so by the time it runs the remote dispatch exists and the implementation should call it for real.&lt;/p&gt;

&lt;p&gt;TDD, implementation and review go to the loop with nobody watching. The model is sonnet throughout, and each feature has a budget ceiling for the whole run. Once a feature converges, the coordinating session reads the diff against the design, runs the three checks itself, and opens a PR; the release, deploy and acceptance commands are its job too. What I do is merge PRs, read the quality report and the retro, and decide whether it ships. Exactly two places need a human: deciding what to build, and deciding whether it ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the loop
&lt;/h2&gt;

&lt;p&gt;pdlc's own loop engine is &lt;code&gt;/pdlc-loop-run&lt;/code&gt;. Starting from the current stage, it hands each segment — TDD, implementation, review — to a fresh subagent, reads the state file after each one, and consults a fixed table to pick the next step. It stops at &lt;code&gt;review_done&lt;/code&gt; and never releases anything itself. There are two layers here: one process per feature on the outside, and inside each process, loop-run dispatching one subagent per segment. The guardrails are a step cap of 4, stop on a failed step, and stop if the state didn't move.&lt;/p&gt;

&lt;p&gt;It handles one feature at a time. Running several in parallel needs a scheduling layer around it, which here is a bash script of a little over 350 lines. It reads &lt;code&gt;depends_on&lt;/code&gt; from each feature's state file to order them, starts anything without a prerequisite immediately, and for anything with one, waits for the prerequisite to converge and branches off it. Each feature gets its own git worktree, and each feature gets one process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;--model&lt;/span&gt; sonnet &lt;span class="nt"&gt;--max-budget-usd&lt;/span&gt; 20 &lt;span class="nt"&gt;--permission-mode&lt;/span&gt; acceptEdits &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"/pdlc-loop-run &lt;/span&gt;&lt;span class="nv"&gt;$fid&lt;/span&gt;&lt;span class="s2"&gt; --max-steps 4 --autonomous"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the process exits, the script reads the state file and commits the work. It also polls that file every 15 seconds to record when stages actually changed, because the timestamps the model writes into the state file can't be trusted.&lt;/p&gt;

&lt;p&gt;Cross-node review and origin filtering started together. Origin filtering was the fastest: three steps, 30 minutes. Cross-node review took 51, and 13 seconds after it converged the script branched off it and started benchmark flags, which took another 37. All three reached &lt;code&gt;review_done&lt;/code&gt; in 88 minutes, each in 3 steps. Nothing hit a rate limit, no step exhausted its budget, and nothing stopped along the way.&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%2F1t8pkv8vdj9sxxpmzdet.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%2F1t8pkv8vdj9sxxpmzdet.png" alt="Timeline of the three features: two parallel tracks, the duration of each step, benchmark flags starting after its prerequisite converged" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing from the run is worth writing down. The three features did not agree on stage names in their state files: two wrote &lt;code&gt;review_done&lt;/code&gt; at convergence, one wrote &lt;code&gt;review&lt;/code&gt;, and one wrote its TDD step as &lt;code&gt;tdd_done&lt;/code&gt;. Read literally, a &lt;code&gt;_done&lt;/code&gt; suffix means finished, so the loop could have taken TDD for convergence and stopped there. loop-run wasn't fooled and started the implementation step as usual. But it does mean you cannot decide whether something moved forward from the stage name alone. You have to look at whether the next-step field changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time and output
&lt;/h2&gt;

&lt;p&gt;Steps, machine time and diff size per feature, with new test cases in parentheses.&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%2F0x84l5igdsalzstli7ez.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%2F0x84l5igdsalzstli7ez.png" alt="Steps, machine time, code, test and documentation lines for the three features and for filling the quality gate" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The three features added 3351 lines, 1770 of them tests, roughly three times the feature code itself. PRDs and designs are counted separately at 1833 lines. Unit tests went from 421 to 516, E2E cases from 52 to 65, coverage from 89.6% to 90.3%.&lt;/p&gt;

&lt;p&gt;The whole line ran like this: draft the requirements, generate the PRDs, review the designs, start the three features, all converged 88 minutes later, merge the branches, run the quality report, red. Fill in what was missing, report passes, release v0.3.0, deploy to two machines, then acceptance on real hardware. My own time is an estimate, something like two and a half hours, spent writing requirements, reviewing designs, checking each feature after it converged, merging, and filling the gate.&lt;/p&gt;

&lt;h2&gt;
  
  
  What holds quality up
&lt;/h2&gt;

&lt;p&gt;With nobody watching, quality rests on four layers.&lt;/p&gt;

&lt;p&gt;The first is an objective check on every step. Which commands a step has to run is written in &lt;code&gt;test-commands.yml&lt;/code&gt;, and only the exit code counts, not the model saying it checked. The TDD step verifies that the newly written tests really fail. Implementation and review verify unit tests, coverage and lint, and two of the three features carried E2E as well. The 85% coverage threshold is a command-line argument. pre-commit runs lint and pre-push runs the unit tests, both taken from that same file. Across three features and three steps each, not one recorded check came back red.&lt;/p&gt;

&lt;p&gt;The second is the review after convergence. The coordinating session reads the diff against the design and runs the three checks itself before opening a PR. All three diffs matched their designs, and the single correction in this run happened earlier, at design review, the one described above. Merging produced four conflicts across three files, mostly both sides adding a field, where keeping both is the answer. Then the full suite again: 516 unit tests, 90.3% coverage, 56 E2E cases, all green.&lt;/p&gt;

&lt;p&gt;The third is the pre-release quality report. &lt;code&gt;/pdlc-quality&lt;/code&gt; looks at four things: coverage, E2E core-flow coverage, lint, and a reconciliation between the PRDs and the core-flow registry. The first report was green on the first three and blocked on the fourth. The three new features contributed 19 acceptance items, and not one of them had been registered as a core flow. The report put it plainly: 45 of 45 green does not mean these three features passed the gate, it means the old 45 are still healthy. The subagents inside the loop had in fact written E2E tests for every feature. They just never registered them.&lt;/p&gt;

&lt;p&gt;The fix is not a signature, it's the work. Nineteen items into the registry, 4 of them covered by tests that already existed, 9 new E2E tests for the rest. The second report passed all four: 64 core flows, 65 cases, all actually executed.&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%2Fxt9mj1esz5o0964etsv8.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%2Fxt9mj1esz5o0964etsv8.png" alt="Four quality layers, and the two quality reports: 19 items unregistered on the first, 64/64 passing on the second" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fourth is acceptance on real machines after release. Both machines took the deploy and I put real tasks through them. Origin filtering was configured on the live console, with the acceptance and benchmark origins on the mute list, and every task after that carried its origin tag. The behaviour of that filter is verified in E2E: a matching origin suppresses the completion notification, failures still go out.&lt;/p&gt;

&lt;p&gt;Cross-node review ran for real too. A review task went to the other machine, that machine executed and archived it, and this one pulled the verdict back and showed which machine had done the review. The verdict was a failure, because the claude command on that machine had never been logged in. What this layer caught was an environment problem, but it did exercise the "review failed, how does the verdict get home" path end to end. Acceptance also turned up a missing lock on the result-collection step: two processes running at once would handle the same result twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the loop stops helping
&lt;/h2&gt;

&lt;p&gt;The parts that ran fast are the parts with an objective check. The parts that slowed down or went wrong are the parts where the record was inaccurate.&lt;/p&gt;

&lt;p&gt;Time is the clearest case. The timestamps in the state file are written by the model. The retro tool reads them and reports a median TDD stage of 2.1 hours; the real durations, recorded by the outer script's polling, were 10, 21 and 13 minutes. The inconsistent stage names above are the same problem wearing a different hat.&lt;/p&gt;

&lt;p&gt;So don't build the outer judgement on fields the model wrote. Take durations from the event log and from git commit times, and take progress from the next-step field or from the completion marker the process prints when it exits. Those are also the two improvements this run sent back to pdlc-skills: make stage names consistent, and get timestamps from a command.&lt;/p&gt;

&lt;h2&gt;
  
  
  End of the series
&lt;/h2&gt;

&lt;p&gt;Eight posts: the three-layer model, getting it installed, running the loop, holding quality, making the process visible, and finally one real project from start to finish. All of it is one idea. Move the judgements you can't rely on to where there's an objective check, and a person only has to hold the two ends: what gets built, and whether it ships.&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;Eight posts in, thanks for reading. If you've run something like this on a real project, which part ate the most of your own time? Comments welcome.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>llm</category>
      <category>tdd</category>
    </item>
    <item>
      <title>How pdlc-skills Makes Progress, Change Impact, and Quality Trends Visible</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Sat, 12 Sep 2026 03:06:24 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/how-pdlc-skills-makes-progress-change-impact-and-quality-trends-visible-44me</link>
      <guid>https://dev.to/kanfu-panda/how-pdlc-skills-makes-progress-change-impact-and-quality-trends-visible-44me</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The last post covered the quality chain. This one is about &lt;strong&gt;visibility&lt;/strong&gt;. An AI can push three features forward in an afternoon. If you can't tell where the project stands, what a change will touch, or how the last stretch went, the automation is running in a black box. pdlc has three tools for this: the statusline together with &lt;code&gt;/pdlc-status&lt;/code&gt;, &lt;code&gt;/pdlc-relate&lt;/code&gt;, and &lt;code&gt;/pdlc-retro&lt;/code&gt;. They watch three timescales: right now, before a change, and month by month.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Three tools, one data source
&lt;/h2&gt;

&lt;p&gt;All three only read the state files under &lt;code&gt;docs/.pdlc-state/&lt;/code&gt;. They don't parse documents and they don't guess. Post 3 described how the three layers coordinate through one shared scoreboard; these tools read that same scoreboard and differ only in the question they answer. The statusline and &lt;code&gt;/pdlc-status&lt;/code&gt; answer "where are we now?". &lt;code&gt;impact&lt;/code&gt; answers "what does changing this touch?". &lt;code&gt;retro&lt;/code&gt; answers "how did this stretch go?".&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%2Fb4jccmywjh7qb30txmda.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%2Fb4jccmywjh7qb30txmda.png" alt="Three tools read the same state directory and answer questions on three timescales: the statusline shows where things are right now, impact checks the blast radius before a change, retro shows the trend month by month" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How accurately the state files are written decides whether what these tools show is true. I'll come back to that at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where are we now: the statusline and /pdlc-status
&lt;/h2&gt;

&lt;p&gt;Here is a statusline entry from a real project, with the stage labels translated (the current release prints them in Chinese):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;● PDLC console-p3 · PRD·Design·TDD·Impl·[Review]·Ship · →ship · 🤖 · ✓unit ✓lint ✓cov · ⏱9d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Left to right: the feature name; the six-stage track (PRD, design, TDD, implementation, review, ship) with the current stage highlighted; the next step; the run mode (🤖 autonomous loop, 👤 manual); the three check results; and how long the feature has sat in the current stage.&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%2Fike7cu4gdu99c9qi75um.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%2Fike7cu4gdu99c9qi75um.png" alt="The six fields of one statusline entry: feature name, six-stage track, next step, run mode, check results, time in stage; below it, the full-line format used when a feature is blocked" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three design choices in this one line are worth spelling out.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It doesn't show "step 4 of 6". A bug fix doesn't go through all six stages, so a counter would mislead. Instead it shows the fixed track and highlights where you are.&lt;/li&gt;
&lt;li&gt;The three checks only show by default in autonomous mode. In manual mode you're running the tests yourself and the ticks are noise. Their value is being able to tell at a glance whether an unattended loop is healthy.&lt;/li&gt;
&lt;li&gt;When a feature is blocked, the whole line changes format: &lt;code&gt;⛔ PDLC xxx blocked: needs a product decision · ⏱12m&lt;/code&gt;. A loop that has stopped and is waiting for a human must be the first thing you see. That is the statusline's main job.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One command turns it on: &lt;code&gt;/pdlc-settings statusline&lt;/code&gt;. It appends itself after whatever statusline command you already have and leaves the rest alone. &lt;code&gt;/pdlc-status&lt;/code&gt; is the command-line view of the same data: in progress, done, and suggested to-dos, plus a relation tree if the relation index exists. It verifies rather than just listing. When three features had sat at "review done, not shipped" for over ten days, it went to the CHANGELOG and the git tags to confirm that nothing had actually shipped. &lt;code&gt;--stale 3&lt;/code&gt; tabulates how many days each feature has been sitting.&lt;/p&gt;

&lt;p&gt;That is as far as a tool goes: it puts the problem in front of you. What to do about it is a person's call.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does a change touch: the relation graph
&lt;/h2&gt;

&lt;p&gt;Which feature extends, depends on, or replaces which: there are six relation types. Four are directed: &lt;code&gt;extends&lt;/code&gt;, &lt;code&gt;depends_on&lt;/code&gt;, &lt;code&gt;supersedes&lt;/code&gt;, &lt;code&gt;resolves&lt;/code&gt;. Two are symmetric: &lt;code&gt;conflicts_with&lt;/code&gt;, &lt;code&gt;relates_to&lt;/code&gt;. Nobody fills these in by hand. When &lt;code&gt;/pdlc-feature&lt;/code&gt; assigns a feature ID it scans the existing features, and &lt;code&gt;/pdlc-prd&lt;/code&gt; scans the requirements text for words like "based on", "extends", "depends on", and "replaces"; whatever it finds goes into the PRD and the state file with a reason attached. In one real project with three iterations, phase 2 and phase 3 both extend phase 1, and phase 1 extends the original MVP.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;rebuild&lt;/code&gt; once and it scans the state files, builds an index of nodes and edges, and draws a mermaid graph. The MVP predates the project's adoption of pdlc and has no state file. Rather than reporting a dangling reference, rebuild kept it as a historical terminal node.&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%2F29k15l37ld00jdwiwoqm.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%2F29k15l37ld00jdwiwoqm.png" alt="The example project's relation graph: phase 2 and phase 3 extend phase 1, phase 1 extends the MVP; running impact on phase 1, red marks the direct downstream features and green the historical node" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;impact&lt;/code&gt; is the reason the graph exists. Run it on phase 1 and the output has three tiers: 🔴 direct impact (phase 2 and phase 3), 🟡 indirect impact (anything one hop further; none here), 🟢 historical (the MVP, audit only). It also gives advice: phase 1 is already extended by two features that have passed review, so a change to it should be a new feature that &lt;code&gt;supersedes&lt;/code&gt; it, not an in-place edit, or the downstream review results become void.&lt;/p&gt;

&lt;p&gt;The other subcommands: &lt;code&gt;query&lt;/code&gt; shows one feature's inbound and outbound edges, &lt;code&gt;orphans&lt;/code&gt; lists features with no relations at all, and &lt;code&gt;validate&lt;/code&gt; checks five rules: dangling references, self-references, cycles, contradictory pairs, and whether symmetric relations are recorded on both sides. &lt;code&gt;set&lt;/code&gt; is the only one that writes state files: add a symmetric relation and both files get a line, then the index is rebuilt.&lt;/p&gt;

&lt;h2&gt;
  
  
  How did this stretch go: the retrospective
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/pdlc-retro&lt;/code&gt; looks at the last 30 days by default and aggregates the history in the state files into a report: features delivered, self-check pass rate per stage, median stage duration, and sticking points, written to a monthly file under &lt;code&gt;docs/07_reviews/retro/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pass rates from one real run: requirements, design, and TDD at 100%, implementation 93.8%, review 54.9%. The rate is the share of self-check items that passed. The forty-odd percent that didn't pass at review are the items flagged for a person to decide, about seven per feature.&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%2F3kjkw7ypc1qwsao10j2g.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%2F3kjkw7ypc1qwsao10j2g.png" alt="Retrospective for the example project: self-check pass rate and median duration for the five stages; human intervention is concentrated in review" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That number is right. The first four stages settle everything a machine can judge, and whatever it can't judge is left for review. A low review "pass rate" means the earlier stages did their job. If review also came out at 100%, I'd want to know whether it actually looked.&lt;/p&gt;

&lt;p&gt;Median durations: requirements 0.0 hours, design 0.1, TDD 0.6, implementation 0.9, review 5.0. Take the review figure with a grain of salt. It measures wall-clock time from entering review to finishing it, overnight hours included, not working time.&lt;/p&gt;

&lt;p&gt;How the report handles bad data is worth noting. One feature's review had a completion timestamp earlier than its implementation. Instead of producing a negative duration, the report dropped the sample and listed it separately as "data anomaly, check the write timing". Re-run with a seven-day window that contained no activity, and all four sections said "no data" and explained why. Same rule as the false greens in the last post: if it can't be judged, say so, and never paint it green.&lt;/p&gt;

&lt;h2&gt;
  
  
  The limit: they only show what was recorded
&lt;/h2&gt;

&lt;p&gt;All three tools only read state files; none of them checks the code. The state files are written by the AI at the end of each stage, and they drift. When they do, the tools don't fail; they quietly show one item less or count one stage less. The example project has two cases. The check keys: older features wrote &lt;code&gt;tests_green&lt;/code&gt;, newer ones use the standard &lt;code&gt;tests_pass&lt;/code&gt;, and the statusline only reads the standard set, so the older features' checks don't show. And the history has no start timestamps, so durations can only be computed from consecutive completion times. Relations are the same: they're recorded automatically once, at kickoff. If the requirements change later, you &lt;code&gt;set&lt;/code&gt; the new relation yourself.&lt;/p&gt;

&lt;p&gt;So the precondition for all three tools is treating the state files as data to be maintained: fields, timestamps, and relations written to spec.&lt;/p&gt;

&lt;h2&gt;
  
  
  Once you can see
&lt;/h2&gt;

&lt;p&gt;Back to the opening question: the AI pushes three features in an afternoon, so how does a person keep up? Each tool answers one question, where things are, what a change touches, how the stretch went, and all the answers come from the same state files, with no digging through documents and no guessing. They don't make decisions. Whether to push a stalled feature, whether to touch a baseline, how to schedule the items review left for a person: still a human call, now made with data in hand. When the statusline is missing an item or the retro is missing a stage, suspect the records first, then the tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next post
&lt;/h2&gt;

&lt;p&gt;With the three tools covered, the mechanics part of this series is done. Next time we go back to a real project and walk it from the first command to the last release, to see how all of this gets used once it's installed.&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;What's the longest any feature in your project has sat untouched? Comments welcome.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>testing</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>How pdlc-skills Keeps Quality Up When AI Writes the Code</title>
      <dc:creator>kanfu-panda</dc:creator>
      <pubDate>Thu, 03 Sep 2026 15:32:08 +0000</pubDate>
      <link>https://dev.to/kanfu-panda/how-pdlc-skills-keeps-quality-up-when-ai-writes-the-code-42fk</link>
      <guid>https://dev.to/kanfu-panda/how-pdlc-skills-keeps-quality-up-when-ai-writes-the-code-42fk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The last post covered how the loop runs on its own. The faster it runs, the sharper an old question gets: &lt;strong&gt;who vouches for the quality of what the AI produces?&lt;/strong&gt; It doesn't get tired. In one afternoon it can write more code than a person can review in days. This post is about how I handle that in pdlc: not with one gate, but with a chain of seven links.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why quality matters more when AI writes the code
&lt;/h2&gt;

&lt;p&gt;Code quality used to rest on two things: the person writing it had a feel for whether it was right, and there wasn't so much of it that reviewers couldn't keep up. AI removes both at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It has no "feel for whether it's right."&lt;/strong&gt; Ask an AI to grade its own work and it grades generously. It isn't lying; it genuinely thinks it did fine. That's why in pdlc the model's self-check is recorded in its own column and never feeds into any stop-or-continue decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The volume changed too.&lt;/strong&gt; The unattended run from the last post finished a three-phase iteration in one afternoon: four backend API groups, three frontend pages, a full set of notification rules. That used to be days of work. Output sped up; "is this correct?" did not. Same eyes, same hours.&lt;/p&gt;

&lt;p&gt;That gap is the risk. The faster you go, the further a mistake travels before anyone notices. So quality assurance isn't the thing slowing you down; it's the brakes and steering that make the speed usable. And it clearly can't be a human reading every line, because that hands back the time you just saved.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version: seven links, one chain
&lt;/h2&gt;

&lt;p&gt;I split quality into seven links:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements → Design → TDD → Implementation → Unit tests → E2E → Review by a different AI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first two are written by AI, reviewed by AI, and checked once by a human at the end. The middle four are enforced by machine with no room for argument: TDD sets the red light, implementation is judged by exit codes, unit tests have to be plentiful, E2E guards only the core flows. The last link hands review to a different AI. The links are in series, not in parallel: if one fails, the guarantees of the ones before it are worth less. Get the requirements wrong and the strictest testing only builds the wrong thing more solidly.&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%2Flgvhiirt2ca178or7niq.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%2Flgvhiirt2ca178or7niq.png" alt="The seven links of the quality chain: requirements and design are written by AI, reviewed by AI and checked by a human; TDD, implementation, unit tests and E2E are enforced by machine; the final review goes to a different AI" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here they are in order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links 1 and 2: requirements and design. AI writes, AI reviews, a human checks
&lt;/h2&gt;

&lt;p&gt;Counting requirements and design as quality control might seem odd, but they sit furthest upstream: they decide what every test after them is actually verifying.&lt;/p&gt;

&lt;p&gt;Both documents are written by AI. The PRD stage has an eight-point self-check: is the background and goal clear, are there enough user stories, are the acceptance criteria measurable, does the feature list carry priorities, and so on. Fail the self-check and you don't move to the next stage. That last item looks the least important; by the time we get to false greens you'll see it's the one that bites.&lt;/p&gt;

&lt;p&gt;Once written, a different AI reviews it first, and a human checks it last. The order matters. If a human had to write and proofread requirements and design from scratch, the faster the AI produced, the more the human would be the bottleneck, which is the gap we started with. &lt;strong&gt;The human's job is to check, not to execute.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But that check can't be skipped. Whether to build it, where the boundaries are, how to split it: those are judgment calls, and no command returns an exit code for them. That's why the autonomous loop from post 5 never touches these two links and only takes over &lt;code&gt;TDD → implement → review&lt;/code&gt;. What a machine can detect goes to the machine; what it can't stays with a person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Link 3: TDD. Write the failing tests first
&lt;/h2&gt;

&lt;p&gt;Before any code, write a batch of tests that are guaranteed to fail. This isn't "we recommend writing tests first"; it's a hard requirement. And it buys something concrete: from this moment on, "is it done?" has an answer that doesn't depend on the model. Run the tests. Exit code 0 means done; anything else means not done.&lt;/p&gt;

&lt;p&gt;This gate only holds if the &lt;code&gt;test-commands.yml&lt;/code&gt; from the last post is in place. The verdict comes entirely from running commands. The model saying "I think it's good" doesn't count here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Link 4: implementation. Judged by exit codes only
&lt;/h2&gt;

&lt;p&gt;Now the code gets written. People assume this step can't be controlled: the AI writes it, and you can't watch every line. In fact it's the most tightly controlled step, because there's a check on the way in and another on the way out.&lt;/p&gt;

&lt;p&gt;The way in checks one thing: &lt;strong&gt;the relevant tests must exist, and they must be red right now.&lt;/strong&gt; This is one of pdlc's iron rules. If no tests are found, the implement command refuses to run and sends you back to TDD. "I'll write the code first and add tests later" isn't accepted.&lt;/p&gt;

&lt;p&gt;Writing the code has one rule: the minimum code that turns the tests green, then refactor under their protection. The rule targets the laziest route an AI can take. When a test fails, editing the test is always easier than fixing the code. So the implementation stage isn't allowed to touch test files, and pdlc's automated acceptance suite has an assertion for exactly that: a modified test file is an automatic fail.&lt;/p&gt;

&lt;p&gt;The way out has three checks: unit tests, coverage, lint. All three run real commands and read exit codes. Lint means zero warnings, not "fewer warnings than last time." The results go into the state file, and pdlc is explicit that these three fields may only hold command exit codes; the model's own assessment can't stand in for them. One failure and the stage isn't complete, and the flow doesn't advance.&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%2Fw7f9urnbibr2734m8oc3.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%2Fw7f9urnbibr2734m8oc3.png" alt="Implementation and the code review that follows it: implementation requires red tests on the way in and three exit codes on the way out; code review only accepts green tests, flags what it can't fix for a human, and writes blocked when it hits a product decision" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Getting through that door isn't the end. The code goes to review next, and review has its own entry condition: if the tests aren't fully green, review doesn't start. Between implementation and review sit the next two links.&lt;/p&gt;

&lt;h2&gt;
  
  
  Link 5: plenty of unit tests, but they only prove the parts
&lt;/h2&gt;

&lt;p&gt;With those two gates in place, the next job is building up the unit tests. One of my larger projects has over 4,000 unit tests and 90%+ coverage. But at that scale I'm also clearer about their limit: unit tests prove each part is correct on its own. That's all they prove.&lt;/p&gt;

&lt;p&gt;There's a number people treat as insurance: coverage. It measures "this line was executed," not "this logic is correct." This test maxes out a function's coverage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calculates order total&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calcTotal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeDefined&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function ran, the branches ran, the report shows green. Whether the total is right, this test says nothing. Nobody is cheating here; coverage can only see execution, never assertions. The more you use it as an acceptance criterion, the more it drifts toward "make the number look good."&lt;/p&gt;

&lt;p&gt;So I still write 90%, but what it proves is "the tests are spread wide," not "the quality is high." For that, you need the next link.&lt;/p&gt;

&lt;h2&gt;
  
  
  Link 6: E2E for the core flows
&lt;/h2&gt;

&lt;p&gt;The same project has just over a hundred E2E tests for its core business flows. Four thousand to a hundred: the ratio itself tells you how the work is divided.&lt;/p&gt;

&lt;p&gt;Production incidents are rarely one function computing the wrong value. Usually it's several individually correct parts that don't fit together: state didn't get passed, the order was wrong, the two sides read a boundary differently. Unit tests can't see this by design. They mock the dependencies away, and the problem lives between the dependencies.&lt;/p&gt;

&lt;p&gt;So the core flows need E2E. I use Playwright driving Chrome against real pages: actually click through, actually wait for the API, actually check what rendered. It's slow and flakier, but it's the only thing that answers "does this flow still work today?"&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%2Futm4d1xbcdziuby28don.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%2Futm4d1xbcdziuby28don.png" alt="Unit tests mock dependencies away and verify a single part; E2E runs real pages and real APIs and verifies the whole flow still works once the parts are connected" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/pdlc-quality&lt;/code&gt; checks E2E bluntly: every core flow has to map to a test in the mapping file, and that test has to show as passed in this run's actual results. One missing is red. "I think another test already covers that flow" isn't allowed to fill the gap; that's exactly the subjective judgment being removed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Link 7: a different AI reviews every stage
&lt;/h2&gt;

&lt;p&gt;The last link is review, and it happens more than once: requirements review, design review, code review, each its own gate.&lt;/p&gt;

&lt;p&gt;The key word is &lt;em&gt;different&lt;/em&gt;. As noted at the start, an AI grades itself generously, and the AI that just designed something and is then asked to review it is no exception. So I start each review separately: a new session, a subagent running a different AI, sometimes a different model. A reviewer with clean context sees what the author can't. The author's mental footnotes ("I considered that, here's why") don't exist in the new session, so whatever the design document actually fails to say finally shows.&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%2F5ltx3k27yfizc1j9ljek.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%2F5ltx3k27yfizc1j9ljek.png" alt="Self-review in the same session is grading your own homework; a subagent running a different AI has clean context and actually finds things" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code review is the most detailed of the three. It checks the implementation against the design document item by item: do the API parameters and return shapes match, is error handling consistent, is there string-built SQL, are there missing auth checks, list endpoints without pagination, N+1 queries. What it can fix on the spot, it fixes. What it can't, such as architectural trade-offs or disputes about business logic, goes into the report marked for a human.&lt;/p&gt;

&lt;p&gt;The reviewer is still an AI, not a person. Human time shouldn't go to "read the whole thing and look for problems"; an AI can do that. People handle only the few points it reports and isn't sure about. When review hits something that needs a human decision, pdlc stops and writes &lt;code&gt;blocked&lt;/code&gt;. The "three config fields with no backend consumer" case from post 5 was caught exactly this way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seven links in place. Now guard against false greens
&lt;/h2&gt;

&lt;p&gt;Chain complete, report all green: can you trust it? Not yet. The dangerous state was never red; red is at least honest. The dangerous state is a false green: everything looks fine while something underneath has already gone wrong.&lt;/p&gt;

&lt;p&gt;There are two kinds, and neither is fixed by trying harder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One: the list rots.&lt;/strong&gt; The E2E coverage matrix compares against a "core flows list," and someone has to remember to update the list. Add a new core flow, forget to add it to the list, and the matrix stays green. It has turned "we don't know" into "we've covered it." That's worse than no check at all, because it comes with a green report that lets you keep being wrong in comfort. The fix is a forced reconciliation against the PRD on every run: in the PRD but not on the list means red, directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two: "can't be judged" gets read as "no problem."&lt;/strong&gt; Remember the least impressive item on the PRD self-check, that feature lists must carry priorities? The reconciliation keys off those P0/P1 marks. If a PRD never had them, extraction yields an empty set; compare that to the list and there's zero drift, so the report says "reconciliation passed." What actually happened is that the entire PRD never entered the check. Old PRDs are the usual victims, and old PRDs are exactly the ones behind the flows already in production.&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%2F26huv5rbfncjb1le3xtt.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%2F26huv5rbfncjb1le3xtt.png" alt="Two sources of false green: list rot lets new flows slip through silently, and a PRD without priority marks never enters the check at all; both produce a green report" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the rule changed: any PRD that skipped reconciliation for lack of priority marks must be listed separately as a warning, and the reconciliation item can't be marked passed, only "⚠️ no drift, but N PRDs could not be judged." It's the same principle as post 3's "no command to run means leave the cell empty, never fill in pass": if you can't measure it, write "not measured," and never let a blank pose as green.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this doesn't catch
&lt;/h2&gt;

&lt;p&gt;Seven links plus false-green guards still leave things out of reach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If the requirements themselves are wrong, it's green anyway.&lt;/strong&gt; The chain guarantees "what you meant to build was built solidly," not "this was the right thing to build."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It doesn't guarantee you actually set everything up.&lt;/strong&gt; I have my own counterexample: a smaller project where unit tests and E2E both run, but coverage tooling was never configured. With a link missing, you don't get to say "quality is assured." Installing pdlc doesn't make you compliant; it lists what needs doing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A human still signs off.&lt;/strong&gt; &lt;code&gt;/pdlc-quality&lt;/code&gt; only turns measured data into a report you can verify. It doesn't rule on pass or fail; whether to ship is a person's call. If the party writing the code is also the party ruling on it, everything that put the machine in charge of the verdict is pointless.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this buys
&lt;/h2&gt;

&lt;p&gt;Back to the gap from the start: AI made output faster and judgment didn't keep up. What these seven links do, in the end, is speed up judgment until it keeps pace.&lt;/p&gt;

&lt;p&gt;For me personally, the result isn't "no bugs"; nobody can promise that. The result is &lt;strong&gt;I'm willing to let it run by itself&lt;/strong&gt;. That unattended afternoon in the last post finished a three-phase iteration with me stepping in three times. Not luck: I know a mistake will get stopped at some link instead of waiting for a user in production to find it.&lt;/p&gt;

&lt;p&gt;The AI will still make the mistakes it was going to make. What the chain does is bring them into the open early, while each one is still a bug and cheap to fix, not after it has become an incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next post
&lt;/h2&gt;

&lt;p&gt;Next time, a change of direction: &lt;strong&gt;visibility&lt;/strong&gt;. How to record dependencies between features, how to tell what a change will touch, whether you can see the state of the project at a glance, and how to keep retrospectives around.&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;This seven-link setup is what I've arrived at on my own projects; it won't fit everyone. If you run a leaner combination, or think one of these links can go, I'd like to hear about it in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>testing</category>
      <category>softwareengineering</category>
    </item>
    <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>
  </channel>
</rss>
