<?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: Shinsuke KAGAWA</title>
    <description>The latest articles on DEV Community by Shinsuke KAGAWA (@shinpr).</description>
    <link>https://dev.to/shinpr</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%2F3448941%2F612feab1-a03c-49be-b329-ae74d583329c.jpg</url>
      <title>DEV Community: Shinsuke KAGAWA</title>
      <link>https://dev.to/shinpr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shinpr"/>
    <language>en</language>
    <item>
      <title>Was the Monorepo Really Best for Coding Agents?</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Thu, 20 Aug 2026 10:55:58 +0000</pubDate>
      <link>https://dev.to/shinpr/was-the-monorepo-really-best-for-coding-agents-2p84</link>
      <guid>https://dev.to/shinpr/was-the-monorepo-really-best-for-coding-agents-2p84</guid>
      <description>&lt;p&gt;Earlier this year, I thought monorepos were the obvious choice for AI-native development.&lt;/p&gt;

&lt;p&gt;The reason was context closure.&lt;/p&gt;

&lt;p&gt;A coding agent works better when the code, tests, design decisions, infrastructure, and development rules it needs are available inside the same execution environment. It should not have to wait for a person to paste a decision from Slack, explain a convention that lives in someone's head, or retrieve a requirement from a system it cannot update.&lt;/p&gt;

&lt;p&gt;A monorepo made that easier. Put the product and its development context in one place, give the agent tools to search it, and the repository becomes a closed environment in which the agent can work.&lt;/p&gt;

&lt;p&gt;I still believe context closure matters. What changed was my view of what the repository was closing.&lt;/p&gt;

&lt;p&gt;I was involved in a discussion about introducing a shared agent harness across a large repository. The technical proposal was not the hardest part. The harder question was what would happen to the workflows engineers already used.&lt;/p&gt;

&lt;p&gt;If the shared harness required people to stop using their personal skills, instructions, and workflows, would they actually do it?&lt;/p&gt;

&lt;p&gt;There was no confident yes.&lt;/p&gt;

&lt;p&gt;By then, the repository already contained more than code. It contained several partially overlapping ways of telling agents how to work, some checked in by teams and others maintained by individuals. Introducing a common harness was no longer an installation. It was a migration away from systems people depended on every day.&lt;/p&gt;

&lt;p&gt;I had seen the opposite failure too. Centralize before the organization knows how to design, evaluate, and maintain a reliable harness, and the shared system becomes a ceiling. Poor instructions affect everyone. Reviewers absorb the correction cost. AI usage remains shallow because the approved path is less effective than what capable individuals could build for themselves.&lt;/p&gt;

&lt;p&gt;The two approaches appeared to fail in opposite directions. Centralize too early, and the organization standardizes what it has not yet learned to do well. Standardize too late, and local workflows become too embedded to replace.&lt;/p&gt;

&lt;p&gt;Where the code lived mattered less than who could define how an agent should work across it, resolve conflicting context, and keep the system correct as both the code and the models changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The repository stopped being the context boundary
&lt;/h2&gt;

&lt;p&gt;The monorepo argument was stronger when coding agents were less capable.&lt;/p&gt;

&lt;p&gt;An agent that could only sustain a short task benefited enormously from having everything nearby. Repository boundaries were practical context boundaries. Work that crossed them required more prompting, more retrieval infrastructure, and more human coordination. Keeping related systems together reduced the chance that the agent would miss something important.&lt;/p&gt;

&lt;p&gt;The current long-running models I use behave differently. Given access to the relevant repositories and tools, they can search across projects, trace dependencies, compare implementations, and make coordinated changes without treating each repository as a separate task. Access still has to be designed, but the repository boundary is no longer the same kind of capability boundary.&lt;/p&gt;

&lt;p&gt;Cross-repository reach does not make the surrounding structure optional. In a monorepo, broad search still needs package, ownership, and domain boundaries to separate relevant code from similar but unrelated code. Across repositories, search depends on a trustworthy inventory and dependency map, or an incomplete result can appear complete. Better models need less assistance to follow that map. They do not remove the need to maintain it.&lt;/p&gt;

&lt;p&gt;This claim is about context acquisition and edit coordination. Repository boundaries still matter for atomic commits, CI, compatibility, and deployment, and better models do not remove those constraints. They do change the monorepo tradeoff for AI development.&lt;/p&gt;

&lt;p&gt;Code visibility is still useful, but visibility is no longer exclusive to a monorepo. An agent can discover an API or inspect a dependent service across repositories. It can update several repositories in one run. Producing the edits is usually easier than determining whether they may be deployed together, which compatibility window must be preserved, and how the rollout should be sequenced.&lt;/p&gt;

&lt;p&gt;As repository boundaries stopped being context boundaries for coding agents, the monorepo's main AI advantage moved from retrieval to governance.&lt;/p&gt;

&lt;p&gt;A monorepo gives product-wide instructions, shared skills, architectural context, and guardrails a common home. The same repository can carry the evaluations and maintenance work that keep them current. That is a real advantage. It is also the part most organizations are least prepared to operate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context closure is not context governance
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://www.norsica.jp/blog/what-makes-development-ai-native" rel="noopener noreferrer"&gt;What Makes Development AI-Native?&lt;/a&gt;, I described context closure as the condition in which product context is searchable, readable, and updatable within the LLM's workflow.&lt;/p&gt;

&lt;p&gt;That remains necessary. But availability answers only one question: can the agent reach the context?&lt;/p&gt;

&lt;p&gt;Governance answers the questions that become important after it can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which context is authoritative?&lt;/li&gt;
&lt;li&gt;Where does it apply?&lt;/li&gt;
&lt;li&gt;Who owns it?&lt;/li&gt;
&lt;li&gt;What happens when two instructions disagree?&lt;/li&gt;
&lt;li&gt;How is an obsolete rule removed?&lt;/li&gt;
&lt;li&gt;How was it evaluated, and who is responsible when local context changes product-wide behavior?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A repository can close context without answering any of these.&lt;/p&gt;

&lt;p&gt;This becomes harder as the organization grows. A product large enough to justify a monorepo is often developed by multiple teams. Those teams are deliberately kept loose enough to work without constant coordination. Their code, architecture, release processes, domain knowledge, and agent workflows diverge because some divergence is necessary for autonomy.&lt;/p&gt;

&lt;p&gt;A team creates a skill to fix a recurring failure. An engineer adds a personal instruction because changing the team's workflow would affect everyone. Another team solves a similar problem differently. Each addition is locally reasonable. Over time, the repository, team, and individual layers accumulate overlapping assumptions about how work should be planned, reviewed, tested, and completed.&lt;/p&gt;

&lt;p&gt;The engineer becomes isolated inside progressively narrower context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;product context
  -&amp;gt; system context
    -&amp;gt; team context
      -&amp;gt; personal context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deeper the local system becomes, the harder it is for that engineer to change the shared one. A personal workaround is cheap. Correcting a repository-wide workflow requires agreement, migration, and responsibility for everyone it affects.&lt;/p&gt;

&lt;p&gt;Local convenience gradually removes the force that would otherwise improve the common system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better models make conflicting context more expensive
&lt;/h2&gt;

&lt;p&gt;Missing context is still dangerous. A model cannot reliably honor a constraint it cannot discover.&lt;/p&gt;

&lt;p&gt;But missing context is no longer the only important failure mode. Incorrect context, conflicting context, and excessive control can be worse because a capable model can execute them more thoroughly.&lt;/p&gt;

&lt;p&gt;I described this shift in &lt;a href="https://dev.to/shinpr/when-better-models-make-old-agent-workflows-worse-1o7m"&gt;When Better Models Make Old Agent Workflows Worse&lt;/a&gt;. Rules written to compensate for earlier model failures can become work-generating constraints, leading the model to create the documents, tests, reviews, retries, approvals, and abstractions they imply. The same problem appears at organizational scale in a monorepo.&lt;/p&gt;

&lt;p&gt;One team skill may require every change to pass several review phases. Another may instruct the agent to choose only the narrowest proof boundary. A product-level rule may preserve a public contract while a local workflow optimizes for an internal replacement. A personal instruction may require a planning artifact that the shared harness no longer uses.&lt;/p&gt;

&lt;p&gt;Each instruction can be defensible in isolation. Their combination can reduce execution quality while appearing more mature because more context and more process are present.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AGENTS.md&lt;/code&gt; at least provides a directory-based preference. Codex loads instructions from the repository root toward the working directory, and instructions closer to the working directory take precedence. That does not prove that the local rule is correct; the product-wide rule may be the one that should win. But it gives the model a deterministic guide when the two disagree.&lt;/p&gt;

&lt;p&gt;Skills are harder to reason about because they use progressive disclosure. The agent initially sees names and descriptions, then decides which full instructions to load for the task. What enters the context depends on how the task is interpreted. When several skills apply, there is no equivalent semantic hierarchy that says a product-level decision must override a team workflow or a personal preference.&lt;/p&gt;

&lt;p&gt;Which instructions enter a task can therefore be hard to predict. Changes in task wording, working directory, or model version can activate different combinations, allowing an organization to improve its harness while quietly reducing performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Centralizing before the capability exists
&lt;/h2&gt;

&lt;p&gt;A natural response is to centralize everything, but a shared harness for a large product requires much more than prompt files. Its maintainers need enough product knowledge to separate durable boundaries from old compensation rules and keep context aligned with the codebase. They also need representative evaluations that expose model regressions and workflows that no longer earn their cost.&lt;/p&gt;

&lt;p&gt;Prompt and context engineering skill is necessary, but not sufficient. A person who understands model behavior but has not developed the product cannot create accurate domain context. A person who knows the product but cannot evaluate agent behavior may encode every historical incident as another permanent rule.&lt;/p&gt;

&lt;p&gt;No small central group can deeply understand every domain in a large monorepo while also keeping pace with model changes. If that group becomes the sole author and gatekeeper, humans become the bottleneck. The common harness drifts away from actual development, teams work around it, and standardization suppresses the very experimentation needed to improve it.&lt;/p&gt;

&lt;p&gt;Usage and spending may still increase even while outcomes stagnate. When a weak workflow is centralized, its limitations become organization-wide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standardizing after local systems are embedded
&lt;/h2&gt;

&lt;p&gt;Letting teams and individuals find what works produces faster initial adoption. Engineers can experiment without changing anyone else's process, and useful practices emerge from real work rather than from a central design exercise. Autonomy without a path to convergence, however, creates its own lock-in.&lt;/p&gt;

&lt;p&gt;A personal skill is not merely a file once someone has shaped daily work around it. It contains learned behavior, trusted shortcuts, and assumptions about how the agent will respond. A team workflow becomes part of planning, review, and delivery. Replacing it has a switching cost even when the replacement is better.&lt;/p&gt;

&lt;p&gt;By the time the organization needs a repository-wide harness, it has postponed the difficult decisions: which local behavior should become shared, who has authority to retire the old systems, and how to prove that migration will not reduce performance. Without those answers, the shared harness joins the existing workflows instead of replacing them.&lt;/p&gt;

&lt;p&gt;This brought me back to the question from the original discussion: would engineers give up the personal systems they already relied on? It had sounded like an adoption question. It was really a question about migration authority. The organization wanted one harness but had never established who could retire the systems it would replace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Centralize governance, distribute its maintenance
&lt;/h2&gt;

&lt;p&gt;If a monorepo is going to provide a common AI development environment, its context and harness need a common authority. Product-wide constraints cannot become optional because a team prefers another workflow. The organization needs one way to decide what is canonical, how conflicts are resolved, and when a rule is obsolete. Common authority, however, does not mean that a central team can do all the work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shared authority needs distributed capability
&lt;/h3&gt;

&lt;p&gt;Engineers need more than the ability to ask a model for code. They need to understand how task framing, context selection, instruction scope, progressive disclosure, verification, and model behavior affect the result.&lt;/p&gt;

&lt;p&gt;Not everyone needs to become a specialist in agent evaluation. Everyone contributing context to the shared system needs enough skill to avoid turning a local preference or historical failure into a product-wide obligation.&lt;/p&gt;

&lt;p&gt;The capability cannot be hidden behind a platform team. Product and system context has owners, consumers, compatibility requirements, and a lifecycle. Personal preferences can remain personal when they affect presentation or reversible working style, but they cannot silently redefine correctness, product behavior, approval boundaries, or completion criteria.&lt;/p&gt;

&lt;p&gt;Teams that own a domain must also own the accuracy of the context that describes it. Some members need explicit capacity beyond immediate delivery: maintaining shared instructions, reviewing cross-domain assumptions, contributing representative tasks, and resolving conflicts in the repository-wide harness. Governance is centralized; its evidence and maintenance are distributed across the organization.&lt;/p&gt;

&lt;h3&gt;
  
  
  The harness should need less context over time
&lt;/h3&gt;

&lt;p&gt;Context quality cannot depend on occasional manual cleanup. References, ownership, duplication, schemas, and retired files can be checked mechanically. Representative tasks can detect whether a model update changes behavior. Conflict cases can test which rule wins when product, system, and team instructions disagree. The harness can measure whether a rule improves accepted outcomes or merely creates more work.&lt;/p&gt;

&lt;p&gt;Automation should concentrate human judgment where it changes a real decision rather than spend it on routine consistency checks. The evaluation set must evolve with both the codebase and the models. A skill that passed six months ago has not earned permanent authority.&lt;/p&gt;

&lt;p&gt;Continuous evaluation is only half of the work. Context and harnesses cannot compensate indefinitely for an inconsistent codebase.&lt;/p&gt;

&lt;p&gt;When two parts of the system solve the same problem differently, an instruction can explain the difference. When five parts do, more instructions become a map of unresolved design debt. The model must spend more tokens discovering which example is current, which exception is intentional, and which pattern is safe to extend.&lt;/p&gt;

&lt;p&gt;The durable response is to reduce the inconsistency itself. Public contracts should be explicit. Invalid dependencies should be mechanically rejected. Types, tests, build boundaries, schemas, and permissions should enforce what prompts currently have to explain. Temporary compatibility paths should be removed instead of accumulating permanent context around them.&lt;/p&gt;

&lt;p&gt;The strongest agent instruction is often a codebase in which the wrong change does not fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Judge governance by the cost of outcomes
&lt;/h2&gt;

&lt;p&gt;How should an organization know whether this governance is working? Usage, generated lines, completed tasks, and total spend reward activity. The relevant economic unit is the total inference cost required to produce one accepted outcome at the required quality without human correction.&lt;/p&gt;

&lt;p&gt;That includes model choice, retries, abandoned runs, review agents, unnecessary artifacts, excessive exploration, and work generated by obsolete instructions. Some of that cost is legitimate. Exploration can establish that no change is needed, but it still belongs in the cost of reaching that outcome. Repeated exploration that better context could prevent should fall over time. A poor harness may still complete the task by consuming more reasoning, but the organization is purchasing inference that its development environment should have made unnecessary.&lt;/p&gt;

&lt;p&gt;The number is a health indicator, not an optimization target. A lower cost is an improvement only while the acceptance bar holds and accepted outcomes stay correct after review.&lt;/p&gt;

&lt;p&gt;If a reviewer has to reconstruct the result, the autonomous workflow did not produce the accepted outcome. This measure also gives the organization credit for restraint. The right outcome may be a small change, reuse, removal of a conflicting workflow, or a decision that nothing should be built. As models become capable of sustaining more work, preventing unnecessary work becomes part of operating them well.&lt;/p&gt;

&lt;h2&gt;
  
  
  The monorepo is not the answer by itself
&lt;/h2&gt;

&lt;p&gt;I still see a strong case for monorepos in AI-native development. One repository can provide a canonical harness, keep product-wide context maintainable through the same workflow as the code, and make shared evaluation and mechanical enforcement easier to operate.&lt;/p&gt;

&lt;p&gt;Realizing those benefits requires common context ownership and distributed product knowledge. Without them, a monorepo can contain more contradictions than an agent can reliably reconcile, while a shared harness can enforce the wrong workflow everywhere. A multi-repository system with deliberate cross-repository access, explicit contracts, and well-governed context may no longer impose the disadvantage it once did for capable agents.&lt;/p&gt;

&lt;p&gt;Repository topology alone cannot decide the outcome. What matters is whether the organization can operate the context system that topology makes possible.&lt;/p&gt;

&lt;p&gt;Conway's law did not stop applying when the executor became a model. The communication structure of the organization shapes the codebase; it now also shapes the instructions, skills, workflows, and evaluation systems through which agents change that codebase.&lt;/p&gt;

&lt;p&gt;If teams are responsible only for local delivery, their agent context will optimize for local delivery. If individuals are rewarded for personal productivity, their best workflows will remain personal. If a central group owns the harness without the participation of domain teams, the harness will reflect the central group's limited view of the product.&lt;/p&gt;

&lt;p&gt;AI-native development therefore requires more than distributing a coding tool or checking a set of skills into a repository. The development process itself has to become an engineering responsibility. Teams must treat product-wide quality as part of their work, maintain the system that turns intent into autonomous execution, and make the codebase consistent enough to require less explanation over time.&lt;/p&gt;

&lt;p&gt;The monorepo once looked like the answer because it put everything the agent needed in one place.&lt;/p&gt;

&lt;p&gt;Now the agent can reach much farther.&lt;/p&gt;

&lt;p&gt;The harder question is whether the organization can agree on what the agent should find when it gets there.&lt;/p&gt;

&lt;p&gt;The repository is no longer the context boundary.&lt;/p&gt;

&lt;p&gt;The organization is.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>monorepo</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Reasoning Effort Is Not a Quality Setting</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Wed, 05 Aug 2026 13:25:25 +0000</pubDate>
      <link>https://dev.to/shinpr/reasoning-effort-is-not-a-quality-setting-5aoe</link>
      <guid>https://dev.to/shinpr/reasoning-effort-is-not-a-quality-setting-5aoe</guid>
      <description>&lt;p&gt;I expected Claude Opus 5 high to produce a better design than Opus 5 medium.&lt;/p&gt;

&lt;p&gt;It did not.&lt;/p&gt;

&lt;p&gt;I had given both configurations the same repository, feature request, and design template. The task was to add dependency-aware execution to &lt;a href="https://github.com/shinpr/galley" rel="noopener noreferrer"&gt;Galley&lt;/a&gt;, an open-source local runtime for supervised, multi-model AI coding. A task could declare other tasks as dependencies, and the daemon would claim it only after all of them had succeeded.&lt;/p&gt;

&lt;p&gt;In the blind evaluation, Opus medium's design received 84 points from Claude and 82 from Codex. Opus high received 68 and 50. They took almost exactly the same amount of time (21 minutes and 12 seconds for medium, 21 minutes and 25 seconds for high), while high processed 2.29 million tokens to medium's 1.56 million.&lt;/p&gt;

&lt;p&gt;My first reaction was that something had gone wrong in the evaluation. I read both critiques again, then the designs and session logs. The scores were not the most interesting part. The designs were.&lt;/p&gt;

&lt;p&gt;High explored waiting deadlines, persisted archive history, additional configuration, more state transitions, recovery behavior for those transitions, and tests for the machinery it had introduced. Much of it was technically plausible. Some of it addressed real failure modes. Taken together, those additions made the requested feature larger and harder to operate.&lt;/p&gt;

&lt;p&gt;Medium explored less. It stayed closer to Galley's existing lifecycle and reused more of the current claim and failure machinery.&lt;/p&gt;

&lt;p&gt;High found more things to think about.&lt;/p&gt;

&lt;p&gt;That was the problem.&lt;/p&gt;

&lt;p&gt;I had treated effort as a quality setting. In these runs, it behaved more like an exploration multiplier.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually measured
&lt;/h2&gt;

&lt;p&gt;The feature was not a self-contained coding exercise. Galley stores tasks as YAML files and moves them through lifecycle directories. Multiple daemon processes may compete to claim work. Adding dependencies affected parsing, scheduling, failure recovery, CLI output, backward compatibility, filesystem error handling, and tests that had to prove execution order without calling an external model.&lt;/p&gt;

&lt;p&gt;I ran seven model-and-effort configurations through four separate phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technical design;&lt;/li&gt;
&lt;li&gt;design review;&lt;/li&gt;
&lt;li&gt;implementation from a common approved design;&lt;/li&gt;
&lt;li&gt;code review of a common implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The configurations were GPT-5.6 Sol medium and high, GPT-5.6 Terra xhigh, GPT-5.6 Luna max, Claude Sonnet 5 high, and Claude Opus 5 medium and high. Within each phase, every configuration received the same repository state and the same inputs. These were four controlled phase comparisons around one feature, not seven end-to-end projects in which an early design changed the later implementation.&lt;/p&gt;

&lt;p&gt;For design review, all seven configurations reviewed the unmodified Opus medium design. Between phases, I worked with the orchestrating LLM to prepare controlled inputs from the original requirements and the recorded artifacts. For implementation, all configurations received the same deliberately revised design. For code review, I fixed the target to the Sonnet high implementation from the implementation phase so every reviewer inspected the same production code and tests.&lt;/p&gt;

&lt;p&gt;I deliberately did not tell the models to produce the smallest possible change or prescribe a convergence method. The request fixed the outcome, constraints, and exclusions; deciding how much machinery they justified was part of the engineering task I wanted to observe. An explicit subtraction rule would test compliance with a supplied convergence strategy, which is a different question.&lt;/p&gt;

&lt;p&gt;The outputs were anonymized and evaluated independently by Claude and Codex against a common rubric. I treat the scores as measurements attached to the artifacts, not as verdicts on which model “won.” Concrete mechanisms, defects, preserved boundaries, and demonstrated failures carry more weight than small differences in averages, so I preserved both critiques when the evaluators disagreed.&lt;/p&gt;

&lt;p&gt;There is one important defect in the design scoring that needs to be stated here rather than hidden in the notes. The original design request said that only runnable queued tasks could be claimed. The prompt used for the later blind scoring weakened this to saying that tasks with unfinished dependencies must not be executed; it omitted the prohibition on claiming them. This affected the later blind scoring of the design artifacts, not the design-review runs discussed below, which received the original requirements. Both Opus designs proposed claiming some unresolvable tasks and failing them afterward, so the omission did not obviously favor only one of them, and the evaluators separated the designs on broader scope and compatibility grounds as well. The design scores are still not absolute measures of requirement compliance.&lt;/p&gt;

&lt;p&gt;In the design phase, both evaluators independently placed Sol high first and Opus high last, so the main direction was not explained by simple provider loyalty. Family and style preference did appear elsewhere, especially in design-review scoring. What I have is a structured case study from one repository, not a population estimate or a model leaderboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What high effort changed in Opus
&lt;/h2&gt;

&lt;p&gt;Opus high did not misunderstand the repository. It inspected the implementation extensively and found real questions around concurrency, archive behavior, timing, recovery, and tests. The difference appeared after discovery: once high found a plausible concern, it was more likely to preserve that concern in the final design.&lt;/p&gt;

&lt;p&gt;A rare race suggested another check. The check introduced a state transition. The transition needed persistence and recovery. The recovery path then needed tests and an operational explanation. Each step followed reasonably from the previous one, but the chain had little pressure to return to the current requirement and ask which mechanisms could be removed.&lt;/p&gt;

&lt;p&gt;On a quick read, parts of the high-effort design looked reassuring. It had considered more failure modes. The overreach became clearer only when I traced each mechanism back to the requested behavior and asked what would stop working without it.&lt;/p&gt;

&lt;p&gt;Opus medium showed many of the same instincts at a smaller scale. It still investigated failure handling and concurrent claims, but it generated fewer branches than it had to rank, combine, or reject. In this run, that amount of exploration fit its ability to turn the result into a bounded design.&lt;/p&gt;

&lt;p&gt;I think of the observed pattern as an exploration-convergence mismatch. Exploration discovers files, contracts, alternatives, side effects, and failure conditions. Convergence decides what matters now, merges issues that share one correction, rejects optional hardening, and produces a result that fits the approved scope. Increasing effort can expand the first activity faster than the second.&lt;/p&gt;

&lt;p&gt;The failure does not look careless. It looks like serious engineering applied to a larger problem than the one currently being solved. In a real codebase, someone still has to own every new state, setting, branch, test, and recovery path after the impressive design document is gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Twenty-two million tokens missed one sentence
&lt;/h2&gt;

&lt;p&gt;The design-review phase showed the same imbalance from another direction.&lt;/p&gt;

&lt;p&gt;Every reviewer received the original requirements, the same design, and the same repository state. The requirement explicitly said that a queued task with unresolved dependencies must not be claimed or executed. The design under review proposed claiming some such tasks first, then recording a failure afterward.&lt;/p&gt;

&lt;p&gt;All seven configurations understood and summarized that mechanism. All seven found real problems elsewhere. Between them they processed 22.64 million tokens and produced 115 findings.&lt;/p&gt;

&lt;p&gt;None identified the direct contradiction with the requirement.&lt;/p&gt;

&lt;p&gt;The reviewed artifact was the Opus medium design from the opening. It was more bounded than the high-effort design and scored better in the blind design evaluation, but it still violated this governing condition. Better scope control and a stronger score did not make it implementation-ready.&lt;/p&gt;

&lt;p&gt;They found partial-write hazards, race conditions, duplicate IDs, stale state, archive behavior, unnecessary scans, failure propagation, notification problems, and recovery gaps. Luna max uniquely followed a dependency cycle outward to a task that was not itself in the cycle. Opus medium found a subtle conflict between stale-claim recovery and a task that had waited for a long time.&lt;/p&gt;

&lt;p&gt;The missing check was simpler than most of what they found. More independent exploration created diversity around the technical consequences of the design; it did not guarantee that anyone returned to the governing request and compared the selected mechanism with it directly.&lt;/p&gt;

&lt;p&gt;The contradiction did not propagate into implementation. Between phases, I worked with the orchestrating LLM to prepare a revised common design from the original requirements and the review evidence. That controlled input kept both waiting and blocked tasks queued. The correction came from dataset preparation at the orchestration boundary, not from any of the seven review artifacts. This separation was deliberate: each phase compared model behavior against one controlled input instead of letting an early artifact determine every downstream result.&lt;/p&gt;

&lt;p&gt;This is why I do not treat a high-scoring review as an approval decision. A review can be relatively strong, contain valuable findings, and still miss the condition that determines whether implementation may proceed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same behavior helped in code review
&lt;/h2&gt;

&lt;p&gt;The code-review phase changed the value of wide exploration.&lt;/p&gt;

&lt;p&gt;The common implementation contained defects outside its normal path. A lightweight task reader interpreted some valid YAML differently from the standard loader. Duplicate task IDs could cause one dependency result to be reused for another task. A partial failure while reading the task store could allow a dependent task to run before success had been established. Some CLI output described a different state from the one used by the daemon.&lt;/p&gt;

&lt;p&gt;Opus high inspected production code, user-visible behavior, performance, and tests. More importantly, it changed a central dependency guard in a safe copy and showed that the main integration test still passed. The test looked like evidence for execution ordering. The mutation demonstrated that it was not sensitive to the behavior it claimed to prove.&lt;/p&gt;

&lt;p&gt;No other configuration established that point as clearly. The blind evaluations reflected this: Opus high received 91 and 93, while medium received 88 and 91.&lt;/p&gt;

&lt;p&gt;The high-effort review still carried the same weakness seen in design. It produced nine findings, six of them minor, split related problems, and did not always rank incorrect execution above a presentation issue. But a review has a downstream consumer. Candidate findings can be merged, reranked, or declined before they become production structure. Missing a defect is often more expensive than discarding an extra review item.&lt;/p&gt;

&lt;p&gt;Design has no equivalent cleanup stage once unnecessary machinery becomes the architecture. The same search behavior that expanded a design helped expose a test that was green for the wrong reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sol showed why this is not a medium-versus-high story
&lt;/h2&gt;

&lt;p&gt;The Sol results moved in a different direction. Sol high received higher blind averages than Sol medium in all four phases, although the size and cost of the difference varied.&lt;/p&gt;

&lt;p&gt;In design, Sol high explored the existing code deeply, initially considered a path that would add work to tasks without dependencies, and then corrected itself before completing the document. It avoided introducing a new persistent lifecycle state and allowed blocked tasks to recover when dependency state changed. Both evaluators placed it first, with scores of 89 and 93.&lt;/p&gt;

&lt;p&gt;The added exploration was useful there. It was also useful in implementation, where the average moved from 66 for medium to 80.5 for high and the resulting implementation covered more meaningful behavior.&lt;/p&gt;

&lt;p&gt;In design review and code review, substantially higher recorded token use accompanied much smaller differences in the measured result. Sol high used 3.24 million tokens in design review compared with medium's 1.13 million, while their averages differed by three points. In code review, high used 4.90 million tokens compared with 3.18 million, with a 2.5-point difference.&lt;/p&gt;

&lt;p&gt;The important observation is not that one effort level beat another. Effort expanded the search frontier in both families. Opus high carried more of that frontier into the final artifact; Sol high more often produced a smaller final result from the broader search. The usefulness of the remaining exploration then depended on whether the phase needed selection, implementation coverage, or review recall.&lt;/p&gt;

&lt;h2&gt;
  
  
  The implementations separated at the edges
&lt;/h2&gt;

&lt;p&gt;All seven implementations handled much of the ordinary dependency flow. They could add the YAML field, wait for unfinished tasks, recognize successful dependencies, display reasons, and pass broad test suites. The models separated where the new feature met existing behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens when only part of the task store can be read?&lt;/li&gt;
&lt;li&gt;Does an alternate or relative path use the same interpretation as the daemon?&lt;/li&gt;
&lt;li&gt;Can malformed input change behavior in an existing command?&lt;/li&gt;
&lt;li&gt;Does a feature that is not being used add a full-store scan to an old path?&lt;/li&gt;
&lt;li&gt;Is a cycle result stable, or does it depend on evaluation order?&lt;/li&gt;
&lt;li&gt;Does a green integration test observe the ordering guarantee, or merely execute two tasks that would have succeeded anyway?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Opus medium produced the implementation with the fewest observed gaps. It connected more of these boundaries without changing unrelated behavior. Luna max implemented the ordinary feature at a much lower estimated API cost, but replaced broader search and display paths, changed the treatment of damaged tasks, and added work even when dependencies were unused. Sol high kept the implementation comparatively small but missed alternate-path behavior and direct daemon-level proof.&lt;/p&gt;

&lt;p&gt;These differences are hard to compress into a pass rate. The feature works until the repository is incomplete, an older path reads the same YAML differently, or the test suite gives confidence without observing the protected behavior. That is not benchmark trivia. It is where software maintenance happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources describe activity, not quality
&lt;/h2&gt;

&lt;p&gt;Across all 28 runs, the logs recorded 167.52 million total tokens. Most were cached input repeatedly read across tool turns, not fresh input or hidden reasoning tokens. The summed active execution time was just under eight hours, excluding human approval waits but including tests and builds; the configurations ran in parallel, so this is not the experiment's wall-clock duration. Applying the standard API prices published on August 3, 2026 produced an estimated cost of $104.58, not an actual CLI subscription charge.&lt;/p&gt;

&lt;p&gt;Those resource figures describe activity, not quality. Luna max processed the most tokens in design review and remained inexpensive because cached tokens were cheap, but it was also the slowest configuration in that phase. Token volume, price, exploration breadth, latency, and artifact quality were separate variables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Effort belongs to the phase
&lt;/h2&gt;

&lt;p&gt;I no longer choose one effort level for a model and carry it through an entire workflow. The useful exploration budget depends on what the phase must produce and whether another stage can remove excess work.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;What additional exploration must earn&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Design&lt;/td&gt;
&lt;td&gt;A smaller justified decision after inspecting the real constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;Coverage of another real contract or execution path without changing unrelated behavior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review&lt;/td&gt;
&lt;td&gt;A supported candidate finding that can still be merged, ranked, or declined downstream&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is related to a conclusion I reached while simplifying an older agent workflow: &lt;a href="https://dev.to/shinpr/when-better-models-make-old-agent-workflows-worse-1o7m"&gt;be strict about boundaries and evidence, but flexible about the route between them&lt;/a&gt;. More capable models made detailed route instructions age badly. These measurements add a second problem. Giving the model more room to search is not sufficient when the phase also requires aggressive subtraction.&lt;/p&gt;

&lt;p&gt;The operational question is therefore not “How important is this task?” Important work does not automatically deserve high effort. The better question is “What will happen to the additional possibilities this configuration finds?”&lt;/p&gt;

&lt;p&gt;If the answer is that they become architecture immediately, uncontrolled breadth is expensive. If they remain review candidates that another step can verify and consolidate, higher recall may be worth buying.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I can and cannot conclude
&lt;/h2&gt;

&lt;p&gt;This comparison used one run per configuration per phase. Another task or another run could change close measurements. Claude and Codex sometimes disagreed by more than twenty points, and the overlap between evaluator families and candidate families leaves room for style preference. The design scoring prompt omitted one original claim constraint. The tools and caching behavior also differed between providers, so raw token totals are useful descriptions of these sessions but imperfect provider-level comparisons.&lt;/p&gt;

&lt;p&gt;The experiment did not isolate an internal mechanism inside Opus or Sol, and I cannot show that a particular latent “convergence ability” caused the outputs. What I can show is the external pattern in this setup: higher effort expanded the work explored; the configurations differed in what they retained; and the value of that retained work changed across design, implementation, and review.&lt;/p&gt;

&lt;p&gt;I also cannot conclude that medium effort is generally better, or that high effort causes overengineering. Sol contradicts both claims. An explicit convergence rule might change the outputs, but testing that would measure the models under a new intervention. Here, I intentionally left engineering selection to the models because that judgment is part of how I use them in real development.&lt;/p&gt;

&lt;p&gt;The result is strong enough to change how I assign effort without pretending to be a universal model ranking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploration is not the finished product
&lt;/h2&gt;

&lt;p&gt;Recent coding models are much better at searching a repository, following effects across components, and generating technically plausible responses to what they find. That creates a new failure mode: a model can discover more work than it can economically judge.&lt;/p&gt;

&lt;p&gt;Reasoning effort pushes on that boundary. Sometimes it exposes the missing execution path that makes an implementation safe. Sometimes it produces the review finding nobody else could prove. Sometimes it turns a small design into a system for managing the risks introduced by the design itself. The setting does not know which one is happening.&lt;/p&gt;

&lt;p&gt;Calling it “high” invites the wrong intuition. High effort is not a higher position on a quality scale. It is a larger search budget handed to a particular model inside a particular phase.&lt;/p&gt;

&lt;p&gt;The practical limit of a coding agent may no longer be how much it can explore. It may be how much of that exploration it can turn back into one coherent change.&lt;/p&gt;




&lt;h2&gt;
  
  
  Complete phase scores
&lt;/h2&gt;

&lt;p&gt;These are the simple averages of the two blind evaluations. They summarize the recorded critiques; they do not override evaluator disagreement or the artifact-level evidence discussed above.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;Design&lt;/th&gt;
&lt;th&gt;Design review&lt;/th&gt;
&lt;th&gt;Implementation&lt;/th&gt;
&lt;th&gt;Code review&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.6 Sol medium&lt;/td&gt;
&lt;td&gt;82.0&lt;/td&gt;
&lt;td&gt;80.5&lt;/td&gt;
&lt;td&gt;66.0&lt;/td&gt;
&lt;td&gt;86.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.6 Sol high&lt;/td&gt;
&lt;td&gt;91.0&lt;/td&gt;
&lt;td&gt;83.5&lt;/td&gt;
&lt;td&gt;80.5&lt;/td&gt;
&lt;td&gt;89.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.6 Terra xhigh&lt;/td&gt;
&lt;td&gt;71.5&lt;/td&gt;
&lt;td&gt;68.0&lt;/td&gt;
&lt;td&gt;66.0&lt;/td&gt;
&lt;td&gt;74.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.6 Luna max&lt;/td&gt;
&lt;td&gt;72.5&lt;/td&gt;
&lt;td&gt;84.5&lt;/td&gt;
&lt;td&gt;79.0&lt;/td&gt;
&lt;td&gt;61.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Sonnet 5 high&lt;/td&gt;
&lt;td&gt;70.5&lt;/td&gt;
&lt;td&gt;71.0&lt;/td&gt;
&lt;td&gt;78.5&lt;/td&gt;
&lt;td&gt;68.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 5 medium&lt;/td&gt;
&lt;td&gt;83.0&lt;/td&gt;
&lt;td&gt;76.5&lt;/td&gt;
&lt;td&gt;94.5&lt;/td&gt;
&lt;td&gt;89.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 5 high&lt;/td&gt;
&lt;td&gt;59.0&lt;/td&gt;
&lt;td&gt;72.5&lt;/td&gt;
&lt;td&gt;91.5&lt;/td&gt;
&lt;td&gt;92.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Methodology notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Human approval wait time was excluded from active elapsed time. Test and build execution time was included.&lt;/li&gt;
&lt;li&gt;Token totals include normal input, cached input, cache writes where applicable, and output. Cached input accounted for most of the total.&lt;/li&gt;
&lt;li&gt;Cost estimates apply the standard API rates available on August 3, 2026 to recorded usage. They are not actual CLI subscription charges.&lt;/li&gt;
&lt;li&gt;Artifacts were anonymized before evaluation. Scores are averages of one Claude evaluation and one Codex evaluation; original disagreements were preserved rather than adjudicated into new scores.&lt;/li&gt;
&lt;li&gt;The candidate and evaluator families overlap, so the blind process removes model-name knowledge but not possible preference for a family-specific style.&lt;/li&gt;
&lt;li&gt;The comparison used one run per configuration per phase and should be read as an instrumented case study rather than a population estimate.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>reviews</category>
    </item>
    <item>
      <title>When Better Models Make Old Agent Workflows Worse</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Sun, 02 Aug 2026 14:11:20 +0000</pubDate>
      <link>https://dev.to/shinpr/when-better-models-make-old-agent-workflows-worse-1o7m</link>
      <guid>https://dev.to/shinpr/when-better-models-make-old-agent-workflows-worse-1o7m</guid>
      <description>&lt;p&gt;I recently watched a coding agent refuse to start an approved implementation.&lt;/p&gt;

&lt;p&gt;The work plan contained this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## WorkPlan Review&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Status**&lt;/span&gt;: approved (2026-08-02)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent found the line and understood the word &lt;code&gt;approved&lt;/code&gt;. Then it asked for approval again because the workflow expected a field named &lt;code&gt;Implementation Approval.Status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nothing was missing in substance. The label was wrong.&lt;/p&gt;

&lt;p&gt;The agent was following a repository-resident workflow I had designed to carry a change through requirements, design, review, planning, and implementation. I had spent months adding status fields, handoff contracts, review gates, retry rules, and escalation paths. Each addition addressed a failure I had actually seen. Together, they had made the workflow brittle enough to stop on a heading.&lt;/p&gt;

&lt;p&gt;I had built the system around an old question: how do I stop the model from losing the path?&lt;/p&gt;

&lt;p&gt;The model could now follow the path. My path had become the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two kinds of constraint
&lt;/h2&gt;

&lt;p&gt;The approval incident exposed a distinction I had missed.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;boundary constraint&lt;/strong&gt; reduces the solution space:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preserve the public API contract.&lt;/li&gt;
&lt;li&gt;Do not perform an irreversible external action without authority.&lt;/li&gt;
&lt;li&gt;Implement the confirmed requirements and keep recorded non-goals out of scope.&lt;/li&gt;
&lt;li&gt;Treat the task as complete only when the required behavior is observable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;strong&gt;work-generating constraint&lt;/strong&gt; creates obligations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always produce three alternatives.&lt;/li&gt;
&lt;li&gt;Require unit, integration, and end-to-end tests for every feature.&lt;/li&gt;
&lt;li&gt;Require a mitigation task, owner, rollback plan, and approval record for every risk.&lt;/li&gt;
&lt;li&gt;Resolve every review finding before continuing.&lt;/li&gt;
&lt;li&gt;Stop when an optional field is absent or uses an unexpected label.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both can look like safeguards. They behave very differently once the model is capable of carrying them out.&lt;/p&gt;

&lt;p&gt;Boundary constraints tell the agent where it may operate. Work-generating constraints are read as requested work. A reliable agent will reliably create the extra artifacts, tests, abstractions, and stop conditions they imply.&lt;/p&gt;

&lt;p&gt;That gave me the principle I now use when changing an agent workflow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be strict about boundaries and evidence. Be flexible about the path between them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why the problem surfaced now
&lt;/h2&gt;

&lt;p&gt;The capability shift behind this is real, although public measurement often trails the models people are using.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://metr.org/time-horizons/" rel="noopener noreferrer"&gt;METR's task-completion time horizon&lt;/a&gt; shows a strong historical increase in the difficulty of software tasks that agents can complete. METR also warns that the benchmark covers well-specified tasks, that capability remains jagged, and that new releases may go unmeasured for weeks or be skipped entirely. As of August 2, its public page was still dated May 8, and even its list of recent unmeasured models had not caught up with later releases.&lt;/p&gt;

&lt;p&gt;Actual usage has moved toward longer execution as well. An analysis of roughly 400,000 coding-agent sessions found a recognizable division of labor: people made most planning decisions, while agents made most execution decisions. The authors describe it as &lt;a href="https://www.anthropic.com/research/claude-code-expertise" rel="noopener noreferrer"&gt;people deciding what to build and the agent deciding how to build it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Neither source proves how today's models behave in my workflow. The model families involved in the failures described here were released after the measurements and benchmarks I found. I did not find a public rerun on those releases.&lt;/p&gt;

&lt;p&gt;That timing matters most for &lt;a href="https://arxiv.org/abs/2605.07769" rel="noopener noreferrer"&gt;FixedBench&lt;/a&gt;. In May 2026, the researchers tested five then-current coding models on 200 issues where the code had already been fixed. The agents still made undesirable changes in 35% to 65% of cases. It is useful evidence that action bias existed in that generation. It is not a current failure rate.&lt;/p&gt;

&lt;p&gt;The more interesting result is what happened when the researchers changed the instruction. Telling the agents to verify first and treat abstention as success reduced edits to already-correct code. On partially fixed code, the same instruction made them abstain when more work was still required. Prompt engineering traded action bias for passivity.&lt;/p&gt;

&lt;p&gt;That is exactly the trap I had created in my own workflow. A model failed once, so I encoded the opposite behavior as a universal rule. When the model or task changed, the compensation remained.&lt;/p&gt;

&lt;p&gt;The strongest evidence here comes from the failure history of this workflow on the current models I use. The studies explain why those failures are plausible and why simple prompt fixes decay. They do not substitute for observing the system itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How reliability started manufacturing work
&lt;/h2&gt;

&lt;p&gt;The strict approval field was only the most visible failure.&lt;/p&gt;

&lt;p&gt;In another run, the workflow stopped before implementation because it could not find external accounting evidence, document approval records, an exact release command, and detailed E2E environment assumptions. The repository, local services, and test tools were available. Most of the implementation could have proceeded. The workflow had converted useful planning context into mandatory readiness gates, then treated every missing gate as a user-owned decision.&lt;/p&gt;

&lt;p&gt;The documents had expanded too. Product requirements and design docs started collecting stakeholder approval, live-service access, release procedures, dashboards, and operational evidence. A work plan for a data-export change included account setup and production concerns even though the requested outcome ended at implementation.&lt;/p&gt;

&lt;p&gt;Review made the expansion worse. During that same planning flow, a reviewer requested a deterministic 20,000-row proof. The planner accepted the finding without asking what decision the proof would change or whether a cheaper boundary check would be enough. The reviewer then found that the proposed proof data contradicted an existing aggregation contract, which triggered another revision. Every step was technically defensible. The loop itself had no economic judgment.&lt;/p&gt;

&lt;p&gt;I had made the reviewer authoritative and the author obedient. “Review until approved” had become “add work until the reviewer runs out of ideas.”&lt;/p&gt;

&lt;p&gt;That is not convergence. It is a ratchet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I changed
&lt;/h2&gt;

&lt;p&gt;I did not solve this by deleting every rule. I changed where the workflow is strict.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decide the outcome before designing the solution
&lt;/h3&gt;

&lt;p&gt;A user request is no longer accepted as an automatically valid implementation scope. Before design, the workflow records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the observable outcome;&lt;/li&gt;
&lt;li&gt;what is required now;&lt;/li&gt;
&lt;li&gt;what describes the current state, a desired future, or speculation;&lt;/li&gt;
&lt;li&gt;explicit non-goals;&lt;/li&gt;
&lt;li&gt;a rough view of implementation cost and structural impact.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost assessment stays rough because this is requirements work, not detailed estimation. Its job is to make a bad tradeoff visible while scope is still cheap to remove.&lt;/p&gt;

&lt;p&gt;“No change” and “reuse what already exists” are valid conclusions, but neither is a default. The agent must inspect enough evidence to decide whether the outcome is already satisfied, partially satisfied, or still requires implementation. That avoids turning FixedBench's action bias into its mirror image.&lt;/p&gt;

&lt;p&gt;This also changes what users need to communicate. A useful request contains the boundary of the current outcome, not just a list of desired features. “Extend the existing authentication path without changing the public response contract” is more valuable than a long list of implementation rules. It states both the result and the point at which design needs to be reconsidered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Give the model decisions, not a predicted route
&lt;/h3&gt;

&lt;p&gt;The old workflow described complete routes: run one agent, populate every field, run another agent, stop on any missing input, repeat until a serialized state appears.&lt;/p&gt;

&lt;p&gt;I now try to give each phase four things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the purpose it owns;&lt;/li&gt;
&lt;li&gt;the evidence that can change its decision;&lt;/li&gt;
&lt;li&gt;the criteria for choosing the next action;&lt;/li&gt;
&lt;li&gt;the smallest result the next consumer needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Run every test lane” predicts a route. “Use the narrowest test that observes the required boundary” provides a decision criterion. Exact schemas still matter where software parses the response. A human-readable work plan does not need to fail because two headings express the same approved state. I changed the approval check to accept semantically equivalent evidence instead of requiring one heading.&lt;/p&gt;

&lt;p&gt;The main agent also owns lightweight resolution. It can interpret semantically equivalent states, resolve repository-local ambiguity, retry with new evidence, and continue unaffected work. User escalation is reserved for decisions that belong to the user: a changed product outcome, a new requirement, a major approved design change, unavailable authority, or an irreversible external action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let review findings be declined
&lt;/h3&gt;

&lt;p&gt;The receiver of a review now has three choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apply&lt;/strong&gt; a finding that contradicts an approved requirement, accepted design, repository rule, or observable correctness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decline&lt;/strong&gt; a finding that adds scope, reverses an exclusion, duplicates proof, requests optional hardening, or costs more than its observable effect justifies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return for user decision&lt;/strong&gt; when resolution changes the product outcome or a major approved decision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A decline includes evidence and goes back to the reviewer. The reviewer may maintain the finding when that evidence still leaves the result incorrect or unverifiable. Repeating the same preference without new evidence does not block the workflow.&lt;/p&gt;

&lt;p&gt;A useful review process preserves a basic engineering skill: deciding not to implement a technically reasonable suggestion.&lt;/p&gt;

&lt;h2&gt;
  
  
  The constraint I had to put back
&lt;/h2&gt;

&lt;p&gt;Removing rules can be just as careless as adding them. I proved that during this rewrite.&lt;/p&gt;

&lt;p&gt;The planning flow generated integration and E2E test skeletons so the first vertical slice could prove an acceptance criterion across a real boundary as early as possible.&lt;/p&gt;

&lt;p&gt;After I simplified the handoff, the planner treated the generated test skeleton as an unrelated file and planned a new E2E test later in the project. The artifact still existed, so the workflow looked complete. Its reason for existing had disappeared.&lt;/p&gt;

&lt;p&gt;I restored the skeleton's purpose in the planner: consume the exact generated file in the earliest task that can make its boundary executable. Shared infrastructure may come first only when no acceptance criterion can work without it, and only the infrastructure needed by that first slice belongs there.&lt;/p&gt;

&lt;p&gt;This is a boundary constraint worth keeping. It connects a planned implementation to observable proof and prevents integration risk from being postponed until every component has been built. Removing it made the workflow smaller and less reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What remains strict
&lt;/h2&gt;

&lt;p&gt;Several controls still earn their cost:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User approval for product requirements and major design decisions.&lt;/li&gt;
&lt;li&gt;Explicit authority and mechanical containment for irreversible actions.&lt;/li&gt;
&lt;li&gt;Exact schemas at genuinely machine-consumed boundaries.&lt;/li&gt;
&lt;li&gt;Plans for work with real dependencies.&lt;/li&gt;
&lt;li&gt;Early vertical proof of an accepted outcome.&lt;/li&gt;
&lt;li&gt;Observable verification before completion.&lt;/li&gt;
&lt;li&gt;Independent review where a separate perspective can catch false confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For dangerous operations, sandboxes, restricted credentials, isolated filesystems, and network controls are stronger than long prompt instructions. They &lt;a href="https://www.anthropic.com/engineering/how-we-contain-claude" rel="noopener noreferrer"&gt;limit the blast radius&lt;/a&gt; even when judgment is imperfect. Repeated approval prompts are a weaker substitute: one implementation report describes high approval rates and declining attention, and responds by &lt;a href="https://www.anthropic.com/engineering/claude-code-auto-mode" rel="noopener noreferrer"&gt;using automated judgment to reduce routine prompts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The same division applies to the workflow as a whole. Enforce the durable boundary mechanically where possible. Let the model choose among reversible actions inside it. An account of an agent-first engineering environment uses a similar principle: &lt;a href="https://openai.com/index/harness-engineering/" rel="noopener noreferrer"&gt;treat the top-level instructions as a table of contents rather than an encyclopedia&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four questions I now ask
&lt;/h2&gt;

&lt;p&gt;I now use four questions when reviewing an existing rule:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What changes if I remove it?&lt;/strong&gt; Name the decision, irreversible boundary, downstream consumer, or observable failure it affects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does it limit scope or create work?&lt;/strong&gt; Keep durable boundaries. Require current evidence before generating artifacts, test lanes, approval records, retry loops, or operational tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can the model choose from evidence?&lt;/strong&gt; Replace exhaustive branches with a purpose and selection criteria when the choice is reversible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does it work in a fresh session?&lt;/strong&gt; Rerun a representative task from the beginning. Continuing the old conversation only proves that a human can steer around the failure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The fresh-session test has to cover both sides. A small change should remain small, ordinary ambiguity should not return to the user, and optional review findings should not expand scope. Required tests, approvals, and quality checks must still run. Fewer rules are not evidence of a better workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  A workflow can become technical debt
&lt;/h2&gt;

&lt;p&gt;The hardest lesson for me was that reliability work can itself become overengineering.&lt;/p&gt;

&lt;p&gt;Every workflow rule depends on an assumption about model behavior. A rule added after yesterday's failure can become redundant when the model improves, or harmful when a different task needs the opposite judgment. Status fields and review gates add coupling just as surely as public interfaces and shared abstractions do.&lt;/p&gt;

&lt;p&gt;Boundary constraints age better because they describe what must remain true: the approved outcome, the public contract, the authority available, and the evidence required for completion. The route between those boundaries can change with the model.&lt;/p&gt;

&lt;p&gt;I no longer ask only whether a new rule would have prevented the last failure. I also ask what work it will create, what decision it will remove from the model, and whether it will still make sense after the failure mode disappears.&lt;/p&gt;

&lt;p&gt;The job of an agent workflow is no longer to make a model capable of finishing the process. It is to help a capable model finish the right amount of work.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>promptengineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>A second pair of eyes for Claude Code: building Galley, a local runner that checks the work before the PR opens</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Mon, 11 May 2026 12:16:11 +0000</pubDate>
      <link>https://dev.to/shinpr/a-second-pair-of-eyes-for-claude-code-building-galley-a-local-runner-that-checks-the-work-before-9ie</link>
      <guid>https://dev.to/shinpr/a-second-pair-of-eyes-for-claude-code-building-galley-a-local-runner-that-checks-the-work-before-9ie</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;code&gt;claude -p&lt;/code&gt; pricing changed after this was published, which made running the cross-model loop continuously more expensive than I wanted to defend. Galley's executor is now selectable between Claude Code and Codex (it was Claude-only before), so a same-model Codex → Codex setup is a viable cost-optimized option alongside the original Claude → Codex pairing. See "Where it is" for the current pairing recommendations.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I run three client projects plus an OSS repo. Agentic coding got good enough that for a lot of tasks I just hand over a goal and a list of acceptance criteria and let it run. The catch: Opus 4.7's reliability made me nervous enough that I started ending almost every task with a manual round of "now have Codex look at this."&lt;/li&gt;
&lt;li&gt;That ritual happened often enough that I automated it. &lt;strong&gt;Galley&lt;/strong&gt; is the result: a local runtime where Claude Code executes a task inside a git worktree, then a supervisor (Claude, or Codex when I want a different reviewer) checks the run evidence against the acceptance criteria and either bounces it back for another attempt or approves it and opens a PR.&lt;/li&gt;
&lt;li&gt;The parts I'm happiest with aren't the loop itself. They're the boring scaffolding around it: the tool is installed and configured by a Skill, acceptance-criteria test skeletons get written into the worktree &lt;em&gt;before&lt;/em&gt; the first attempt, there's a per-repo &lt;code&gt;quality.yaml&lt;/code&gt; I keep growing, and a second model on review duty catches things the model that wrote the code does not.&lt;/li&gt;
&lt;li&gt;Galley now does a noticeable chunk of its own development. It's MIT-licensed and available on GitHub.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The setup that made me build this
&lt;/h2&gt;

&lt;p&gt;For the last while my day job has been three concurrent product codebases plus maintaining an open-source workflow framework. None of them are huge, but the context-switching tax is real, and I'd been leaning harder and harder on Claude Code to carry whole tasks rather than babysitting them line by line.&lt;/p&gt;

&lt;p&gt;At some point a threshold got crossed. Not "AI writes all my code now," more like: for a task of a certain size and shape, I no longer needed to plan the implementation. I needed to write down what done looks like (the goal, the acceptance criteria, the paths it's allowed to touch), and that was genuinely enough. The model would go figure out the how. That's a nice feeling the first few times it works.&lt;/p&gt;

&lt;p&gt;Then Opus 4.7 happened, and the feeling got complicated. I won't relitigate it; plenty of people have. The short version for me was: the &lt;em&gt;ambition&lt;/em&gt; was still there, the output still looked plausible, but I stopped trusting "looks plausible." So I started doing something I'd done occasionally before, but now every single time: after Claude Code finished, I'd open Codex, hand it the diff and the requirements, and ask it to find what was wrong. It usually found something. Different model, different blind spots: Codex would flag an edge case Claude glossed over, and Claude would have written cleaner structure than Codex would have. The combination of the two was reliably better than either alone.&lt;/p&gt;

&lt;p&gt;So now every task had a manual final step that I did by hand, with copy-paste, in a separate terminal, every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Third time, automate it"
&lt;/h2&gt;

&lt;p&gt;I have a rule I mostly stick to: the first time you do a thing manually, fine. The second time, grumble. The third time, you build the tool. The cross-model review had blown well past three.&lt;/p&gt;

&lt;p&gt;But the more I sketched it, the more it stopped being "a script that pipes a diff into Codex" and turned into something with a shape: if a supervisor model is going to &lt;em&gt;approve&lt;/em&gt; work, it needs the work in a reviewable form, not just a diff but the command plan, the executor's own report, git status, the structured result. If it's going to &lt;em&gt;reject&lt;/em&gt; work, the rejection needs to come back to the executor as a new attempt with the feedback attached, not as a Slack message to me. And if it can do all that, it can open the PR itself, and I can do final tweaks from PR comments instead of from my editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Galley actually does
&lt;/h2&gt;

&lt;p&gt;It's a local Go binary plus a daemon. You point it at a repo, hand it a task, and it runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your repo  ──task YAML──▶  galley daemon (local)
                               │
                               ├─▶ executor: Claude Code or Codex, inside a git worktree
                               │      writes the code, returns a structured result
                               │
                               └─▶ supervisor: Claude or Codex
                                      reads the run evidence, issues a verdict,
                                      opens the PR on accept
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The task itself moves through a file-backed queue, and the supervisor's verdict decides where it lands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;draft task YAML
        |  galley task queue
        v
   tasks/queued/  →  daemon claims it  →  tasks/running/
        |
        |  Claude Code executes in a git worktree
        v
   supervisor review (Claude or Codex)
        |
        +-- accepted  -------------------→ tasks/done/  (+ open PR if enabled)
        +-- needs_revision  -------------→ retry, while loop budget remains
        +-- needs_supervisor_review  ----→ tasks/failed/  (escalate to me)
        +-- hard_stop  ------------------→ tasks/failed/  (no retry)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything runs locally, every change stays as git-visible diffs, and every attempt writes its evidence to disk: &lt;code&gt;command_plan.json&lt;/code&gt;, &lt;code&gt;run_result.json&lt;/code&gt;, the supervisor's verdict, &lt;code&gt;git_status.json&lt;/code&gt;, &lt;code&gt;diff.patch&lt;/code&gt;. When the loop escalates to me, I'm not guessing; I'm reading the file the supervisor read.&lt;/p&gt;

&lt;p&gt;The task file is the trusted input. It's where the goal, the acceptance criteria (each with an ID the executor has to report back against), the allowed and forbidden paths, the loop budget, and the PR behavior live. The model never gets to redefine its own success criteria mid-run. It gets to satisfy them or fail them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decisions I'd actually defend
&lt;/h2&gt;

&lt;p&gt;The loop is the obvious part. Here's the stuff that took longer to get right and that I think matters more.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Skill installs the tool
&lt;/h3&gt;

&lt;p&gt;This is the bit that still feels a little science-fictional to me. Galley ships an Agent Skill: a Claude Code plugin, and a Codex marketplace entry. You install the &lt;em&gt;skill&lt;/em&gt; first. Then you ask it, in plain language, to set up the repo. It installs the &lt;code&gt;galley&lt;/code&gt; binary, inspects the repository, drafts a &lt;code&gt;quality.yaml&lt;/code&gt; and an &lt;code&gt;environment.yaml&lt;/code&gt;, explains the execution settings to you, writes a valid task YAML, validates it, and queues it. It only queues after you say yes.&lt;/p&gt;

&lt;p&gt;I've shipped CLIs before. The onboarding was always a README and a prayer. Here the onboarding &lt;em&gt;is an agent&lt;/em&gt;, and "explain what this config field means and pick a sensible default for my repo" is just a thing it does. That splits your docs in two: the README is for the human who wants to understand the system, and the skill's reference files are for the agent that has to operate it correctly without you in the loop. They overlap less than you'd think, and I'm still figuring out where each line belongs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Acceptance-criteria test skeletons go in &lt;em&gt;first&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;This one's a direct response to the 4.7 trust problem. There's an optional preflight step. Before the first executor attempt, Galley runs a built-in test-creator pass that writes test skeletons into the worktree, one per acceptance criterion, and records the mapping back onto the running task: for each AC, the skeleton's path, the behavior it's meant to pin down, and where it plugs into the codebase. In a Go repo a skeleton is about what you'd expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestAC1_RunAgentOverridesTimeoutPerCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Skip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AC1: run_agent callers can override execution timeout per call"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// executor fills this in&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those skeleton paths are validated against the task's allowed paths, so the test-creator can't scatter files wherever it likes. And the executor can't get an "accepted" verdict while those tests are still skipped and the required checks haven't run green; the supervisor downgrades that to &lt;code&gt;needs_supervisor_review&lt;/code&gt;. The effect is small but real: the implementation has to converge on something the AC-shaped tests accept. A model that's drifting toward a clever-but-wrong solution runs into the skeleton and has to reckon with it. It's harder to wander off when there's already a fence where the spec said the fence should be. (It's off by default, since some tasks genuinely shouldn't have it, but for "implement feature X with these three behaviors," I turn it on.)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;quality.yaml&lt;/code&gt; is a thing I grow
&lt;/h3&gt;

&lt;p&gt;Each repo gets a quality profile: which checks are required, which review dimensions must pass, what evidence the supervisor should expect, what severity of finding blocks acceptance. It starts small. Then every time a run produces something technically-passing-but-wrong-for-this-codebase, I add a line. Over time the profile becomes the codebase's accumulated opinion about what "good" means here, and both the executor and the supervisor get handed that opinion at the start of every task. Implementations stop drifting because the definition of "done well" stopped being implicit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Claude writes, a second model signs off
&lt;/h3&gt;

&lt;p&gt;Supervisor review defaults to Claude. But I can flip it to Codex per task, and for anything I'd have manually double-checked before, I do. Same-model review (Claude checking Claude) is fine and catches plenty. A different model catches a different category of mistake, and because a rejection comes back as another attempt with the feedback attached, the executor gets to fix what the reviewer flagged instead of just failing the task. So a long unattended run doesn't drift the way an unreviewed one does: every accepted step has had a second model poke at it, and the diff you end up with has those corrections baked in.&lt;/p&gt;

&lt;h3&gt;
  
  
  The deterministic / non-deterministic seam
&lt;/h3&gt;

&lt;p&gt;Building this kind of tool, the genuinely fiddly part isn't the AI calls — it's the boundary between the parts that must be exact and the parts that get to improvise. Two places I had to draw a hard line:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The executor has to return a structured JSON result, every time, or the retry-and-review loop has nothing to stand on; the supervisor can't evaluate a free-form essay. So Galley installs a small guard plugin into the executor's Claude Code that enforces the output format. The creative work is non-deterministic; the envelope it arrives in is not.&lt;/li&gt;
&lt;li&gt;Opus 4.7's defaults made me uneasy enough that I replaced the executor's system prompt outright with one derived from Codex-style prompting and from my own &lt;a href="https://github.com/shinpr/claude-code-workflows" rel="noopener noreferrer"&gt;&lt;code&gt;claude-code-workflows&lt;/code&gt;&lt;/a&gt; OSS, and did the same kind of swap for the supervisor prompts. The task YAML literally has &lt;code&gt;prompt_mode: replace&lt;/code&gt; for this. I'd rather pin the behavior than hope for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither of these is glamorous. Both are the difference between a demo and something I leave running while I'm in a meeting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Galley building Galley
&lt;/h2&gt;

&lt;p&gt;The thing I didn't plan for: once it worked, the obvious next move was to have Galley develop Galley.&lt;/p&gt;

&lt;p&gt;A few recent fixes, all queued through the skill and executed by Galley itself. The PR body was rendering every acceptance criterion as &lt;code&gt;not_satisfied&lt;/code&gt; even when the supervisor had accepted them with evidence, which is confusing for anyone reading the PR. &lt;code&gt;galley task show&lt;/code&gt;, the command I run constantly, was loudly reporting &lt;code&gt;latest_claude_status: failed&lt;/code&gt; on tasks that had actually been accepted with a PR open; true as raw history, wrong as the headline. The PR-comment trigger only recognized &lt;code&gt;/galley rerun ...&lt;/code&gt; and &lt;code&gt;/galley requeue ...&lt;/code&gt;, when what I actually wanted was to type &lt;code&gt;/galley fix the failing test&lt;/code&gt; and have it pick that up as the request. And new worktrees were being branched off whatever the source repo's HEAD happened to be instead of the configured base branch, so one PR's commits could leak into the next.&lt;/p&gt;

&lt;p&gt;Some of those I caught by using the thing. Some — like the test-skeleton preflight — came from sitting down with a pile of &lt;code&gt;runs/&lt;/code&gt; evidence and asking what would have stopped the bad run earlier. Either way, the loop closes: I notice a gap, I write it up as a task with acceptance criteria, Galley implements it, a supervisor checks it, a PR shows up, I tweak it from a comment.&lt;/p&gt;

&lt;p&gt;It's not fully autonomous and I'm not pretending it is. I review the task drafts. I read the escalations. I still tweak PRs. But the ratio of "me describing what I want" to "me typing the code" has tilted further than I expected, and the safety rails (evidence on disk, AC-shaped tests, a growing quality profile, a second model's sign-off) are what let me actually trust the tilt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is
&lt;/h2&gt;

&lt;p&gt;Galley is MIT-licensed and available on GitHub at  &lt;a href="https://github.com/shinpr/galley" rel="noopener noreferrer"&gt;&lt;code&gt;shinpr/galley&lt;/code&gt;&lt;/a&gt;. Both the executor and the supervisor are selectable between Claude Code and Codex. If you want a different model checking the work — the original premise of this post — Claude → Codex is still what I'd reach for; a different model's blind spots are the whole point. Codex → Codex is the cost-optimized alternative: same model on both sides, but the supervisor only ever sees ACs and evidence files, not the executor's conversation, which mitigates self-preference bias even without going cross-model. It's built for trusted local repositories: task YAML is trusted input, quality checks run locally, PR comments can request a requeue but can't rewrite your gates, and only the PR author (who is also a repo owner or collaborator) can drive it from comments. It also leans on &lt;code&gt;git&lt;/code&gt;, a git worktree per task, and &lt;code&gt;gh&lt;/code&gt; for the PR path.&lt;/p&gt;

&lt;p&gt;To try it, add the plugin and let the Galley skill do the setup: it installs the &lt;code&gt;galley&lt;/code&gt; CLI if it isn't already on your &lt;code&gt;PATH&lt;/code&gt;, inspects the repo, drafts the &lt;code&gt;quality.yaml&lt;/code&gt; and &lt;code&gt;environment.yaml&lt;/code&gt; profiles and the task YAML, and queues only after you approve. That "install a skill, have it install the tool" loop is the part that still feels new to me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Claude Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/plugin marketplace add shinpr/galley
/plugin install galley@galley-tools
/reload-plugins
/galley:galley Set up Galley for this repository.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Codex
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex plugin marketplace add shinpr/galley
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That only adds the Galley marketplace. Next, start a Codex session, run &lt;code&gt;/plugins&lt;/code&gt;, select Galley, and install it from there.&lt;/p&gt;

&lt;p&gt;Then invoke the skill with &lt;code&gt;$galley&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$galley Set up Galley for this repository.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you'd rather install the CLI yourself first, it's a one-liner: &lt;code&gt;curl -fsSL https://raw.githubusercontent.com/shinpr/galley/main/scripts/install.sh | sh&lt;/code&gt;. Either way you end up describing tasks to the skill in plain language from there.&lt;/p&gt;

&lt;p&gt;I'm curious how other people have dealt with the same trust gap. Have you put a second model in the review loop? Did a cross-model pairing actually buy you something, or was Claude-reviewing-Claude enough? And if you've found a better answer than "evidence on disk plus tests that go in before the code," I'd genuinely like to hear it. If you build something around this, or break it in an interesting way, even better.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Built a Skill Reviewer. Then I Ran It on Itself.</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Thu, 02 Apr 2026 11:44:56 +0000</pubDate>
      <link>https://dev.to/shinpr/i-built-a-skill-reviewer-then-i-ran-it-on-itself-4m4j</link>
      <guid>https://dev.to/shinpr/i-built-a-skill-reviewer-then-i-ran-it-on-itself-4m4j</guid>
      <description>&lt;p&gt;I built a tool that reviews Claude Code skills for quality issues.&lt;/p&gt;

&lt;p&gt;Then I pointed it at its own source files. It found real problems.&lt;/p&gt;

&lt;p&gt;The irony wasn't lost on me. But the more interesting question is: why did this happen, and what does it tell us about how LLM-based quality tools actually work?&lt;/p&gt;




&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;I maintain &lt;a href="https://github.com/shinpr/rashomon" rel="noopener noreferrer"&gt;rashomon&lt;/a&gt;, a Claude Code plugin for prompt and skill optimization. It includes a skill reviewer agent that evaluates skill files against 8 research-backed patterns (BP-001 through BP-008) and 9 editing principles.&lt;/p&gt;

&lt;p&gt;One of those patterns—BP-001—says: &lt;strong&gt;don't write instructions in negative form.&lt;/strong&gt; Research shows LLMs often fail to follow "don't do X" instructions—negated prompts actually cause &lt;a href="https://arxiv.org/abs/2209.12711" rel="noopener noreferrer"&gt;inverse scaling&lt;/a&gt;, where larger models perform &lt;em&gt;worse&lt;/em&gt;. The fix is to rewrite them positively: instead of "don't skip P1 issues," write "evaluate all P1 issues in every review mode."&lt;/p&gt;

&lt;p&gt;Simple enough.&lt;/p&gt;

&lt;p&gt;Except both my agent definition files had a section called &lt;code&gt;## Prohibited Actions&lt;/code&gt; full of "don't" instructions.&lt;/p&gt;




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

&lt;p&gt;I noticed this by reading my own code. But I wanted to see what happens when the tools catch it—or don't.&lt;/p&gt;

&lt;p&gt;First, I ran the &lt;strong&gt;prompt-analyzer&lt;/strong&gt; agent against both files. It analyzed them, found some issues, but gave the &lt;code&gt;Prohibited Actions&lt;/code&gt; sections a pass. Its reasoning: these qualify as "safety-critical" exceptions to BP-001, since they constrain "destructive" behaviors.&lt;/p&gt;

&lt;p&gt;That felt off. "Don't invent issues not supported by BP patterns" isn't a safety-critical instruction. It's a quality policy. The caller can override or discard the output.&lt;/p&gt;

&lt;p&gt;So I ran the &lt;strong&gt;skill-reviewer&lt;/strong&gt; agent against the same two files. The results were more interesting.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;skill-reviewer.md&lt;/code&gt; (reviewing itself), it flagged all four items in Prohibited Actions as BP-001 violations—P2 severity. Correct call.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;skill-creator.md&lt;/code&gt; (reviewing the other agent), it gave Prohibited Actions a pass. Same structure, same pattern, opposite judgment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The same reviewer, applying the same criteria, reached opposite conclusions on the same construct.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Digging Into Logs
&lt;/h2&gt;

&lt;p&gt;I could have speculated about why. Instead, I checked the subagent conversation logs.&lt;/p&gt;

&lt;p&gt;The skill-creator review log showed this in the Step 1 pattern scan:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;BP-001 (Negative Instructions)&lt;/strong&gt;: Lines 197-202 "Prohibited Actions" section uses negative form. However, per the BP-001 exception in skills.md, these are procedural/irreversible consequences (inventing knowledge, removing examples, overwriting files). &lt;strong&gt;The exception applies.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It did scan for BP-001. It found the section. But it classified the items as "irreversible consequences" and applied the exception.&lt;/p&gt;

&lt;p&gt;The problem was clear: the exception rule said negative form is okay for "safety-critical operations, destructive actions, or order-dependent procedures." That's vague enough to stretch. "Inventing domain knowledge" sounds serious. "Removing user-provided examples" sounds destructive. If you squint, anything can be "destructive."&lt;/p&gt;

&lt;p&gt;Nothing was wrong with the reviewer. It was doing exactly what I told it to do. That was the problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fixing the Criteria, Not the Reviewer
&lt;/h2&gt;

&lt;p&gt;The instinct is to blame the LLM: "it self-justified," "it was biased toward leniency." But the actual cause was simpler: &lt;strong&gt;the exception rule was written in a way that allowed two reasonable readings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The fix wasn't to make the reviewer "smarter." It was to make the criteria harder to misread.&lt;/p&gt;

&lt;p&gt;I replaced the broad exception language:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception: safety-critical operations, exact command sequences,
destructive actions, or order-dependent procedures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a 4-condition checklist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception: Negative form is permitted only when ALL are true:
(1) Violation destroys state in a single step
(2) Caller or subsequent steps cannot normally recover
(3) The constraint is operational/procedural, not a quality policy
(4) Positive rewording would expand or blur the target scope
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And added concrete boundary examples—what qualifies, what doesn't:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Permitted (exception applies)&lt;/th&gt;
&lt;th&gt;Not permitted (rewrite positively)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Do not modify the command"&lt;/td&gt;
&lt;td&gt;"Do not invent issues" -&amp;gt; "Base every issue on BP patterns"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Do not add flags"&lt;/td&gt;
&lt;td&gt;"Do not skip P1 issues" -&amp;gt; "Evaluate all P1 in every mode"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Do not execute destructive operations"&lt;/td&gt;
&lt;td&gt;"Do not create overlapping skills" -&amp;gt; "Verify no overlap before generating"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The key addition: &lt;strong&gt;"Outputs that the caller validates, overwrites, or discards are never irreversible."&lt;/strong&gt; This one sentence eliminates most of the ambiguity. A subagent's output goes to a caller. The caller decides what to do with it. That's not irreversible.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Retest
&lt;/h2&gt;

&lt;p&gt;After updating the criteria, I ran the skill-reviewer again on both files.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;skill-reviewer.md&lt;/code&gt;: Prohibited Actions flagged as BP-001 P2. All four items caught.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;skill-creator.md&lt;/code&gt;: Two items flagged as quality policies that should be positive form. The remaining items—which are genuinely about operational constraints—were accepted.&lt;/p&gt;

&lt;p&gt;Consistent. Explainable. And the reviewer could now articulate &lt;em&gt;why&lt;/em&gt; each item was or wasn't an exception, because the criteria forced it to check specific conditions rather than make a gestalt judgment.&lt;/p&gt;

&lt;p&gt;But I wasn't fully satisfied. In a further round of testing, the reviewer still occasionally applied exceptions loosely—recording "irreversible" in the justification field without explaining &lt;em&gt;how&lt;/em&gt; it's irreversible.&lt;/p&gt;

&lt;p&gt;So I added structured evidence to the output schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"patternExceptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pattern"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BP-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"section heading"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"original"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"quoted text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"conditions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"singleStepDestruction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true|false + evidence"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"callerCannotRecover"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true|false + evidence"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"operationalNotPolicy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true|false + evidence"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"positiveFormBlursScope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true|false + evidence"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can't just write "irreversible" anymore. You have to answer four yes/no questions with evidence. If any answer is no, it's not an exception.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Comes Down To
&lt;/h2&gt;

&lt;p&gt;The criteria had a loophole wide enough to drive a truck through. Better criteria produced better reviews without changing the reviewer at all. The LLM wasn't "inconsistent"—the instructions were ambiguous. Two reasonable people could have read the old exception rule and reached different conclusions too.&lt;/p&gt;

&lt;p&gt;Structured output helped more than I expected. The 4-condition checklist wasn't just about auditability—it changed how the reviewer thinks. When you have to fill in four fields with evidence, you can't hand-wave. The output structure becomes a thinking scaffold.&lt;/p&gt;

&lt;p&gt;And running the tool on its own source files was uncomfortable in a useful way. The temptation is to say "well, I know what I meant." But the tool doesn't know what I meant. It reads what I wrote.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Broader Problem: Skill Quality Is Hard
&lt;/h2&gt;

&lt;p&gt;If you're building Claude Code skills, custom agents, or any kind of structured LLM instruction set—you've probably experienced this: the instructions work fine in your head, but the LLM does something unexpected. You add more instructions. It gets worse. You simplify. Something else breaks.&lt;/p&gt;

&lt;p&gt;The issue is that &lt;strong&gt;you can't see your own blind spots.&lt;/strong&gt; You know what you meant. The LLM reads what you wrote. The gap between intent and text is where bugs live.&lt;/p&gt;

&lt;p&gt;This is why I built &lt;a href="https://github.com/shinpr/rashomon" rel="noopener noreferrer"&gt;rashomon&lt;/a&gt;. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skill review&lt;/strong&gt;: Evaluate skill files against BP-001~008 patterns and 9 editing principles, with structured quality grades&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Golden scenario evaluation&lt;/strong&gt;: Test whether a skill actually &lt;em&gt;works&lt;/em&gt; by comparing execution results with and without the skill, or before and after changes—not just whether it was loaded, but whether it made a measurable difference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The golden scenario part matters. "The skill was loaded" doesn't mean "the skill helped." You need to see the actual output difference to know if your skill is doing anything useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/shinpr/rashomon" rel="noopener noreferrer"&gt;Rashomon&lt;/a&gt; is a Claude Code plugin. Install it and point the skill reviewer at your own skills.&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="c"&gt;# In Claude Code&lt;/span&gt;
/plugin marketplace add shinpr/rashomon
/plugin &lt;span class="nb"&gt;install &lt;/span&gt;rashomon@rashomon
&lt;span class="c"&gt;# Restart session to activate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will find problems. I know because it found problems in itself—and it's better for it now.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your experience with skill quality? Have you found ways to validate that your instructions actually do what you think they do?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>promptengineering</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Same Framework, Different Engine: Porting AI Coding Workflows from Claude Code to Codex CLI</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Wed, 18 Mar 2026 11:50:48 +0000</pubDate>
      <link>https://dev.to/shinpr/same-framework-different-engine-porting-ai-coding-workflows-from-claude-code-to-codex-cli-n3p</link>
      <guid>https://dev.to/shinpr/same-framework-different-engine-porting-ai-coding-workflows-from-claude-code-to-codex-cli-n3p</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I built a &lt;a href="https://dev.to/shinpr/zero-context-exhaustion-building-production-ready-ai-coding-teams-with-claude-code-sub-agents-31b"&gt;sub-agent workflow framework for Claude Code&lt;/a&gt; that solved context exhaustion through specialized agents and structured workflows&lt;/li&gt;
&lt;li&gt;For 8 months, Codex CLI had no sub-agents — the framework was Claude Code-only&lt;/li&gt;
&lt;li&gt;Codex finally shipped sub-agent support — I expected days of migration, it took an afternoon&lt;/li&gt;
&lt;li&gt;What surprised me most: &lt;strong&gt;if you design workflows around agent roles and context separation rather than tool-specific features, your investment survives platform shifts&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The 8-Month Wait
&lt;/h2&gt;

&lt;p&gt;Back in July 2025, I released the &lt;a href="https://github.com/shinpr/ai-coding-project-boilerplate/commit/1a9191dd37e90c7d463f9a26b3a6edf01236d4f2" rel="noopener noreferrer"&gt;first version of this workflow&lt;/a&gt; as a Claude Code boilerplate. By October 2025, it had evolved into a &lt;a href="https://github.com/shinpr/claude-code-workflows/commit/8869e32eeff9d45568a7ca3017688fffdac7e254" rel="noopener noreferrer"&gt;full sub-agent framework&lt;/a&gt; — specialized agents for every phase of development, from requirements analysis through TDD implementation through quality gates. The idea was pretty simple: break complex coding tasks into specialized roles (requirement analyzer, technical designer, task executor, quality fixer...), give each agent a fresh context, and orchestrate them through structured handoffs. No single agent ever hits the context ceiling because no single agent tries to do everything.&lt;/p&gt;

&lt;p&gt;The problem? &lt;strong&gt;Codex CLI had no sub-agent capability.&lt;/strong&gt; Codex had been around since &lt;a href="https://openai.com/index/introducing-codex/" rel="noopener noreferrer"&gt;mid-2025&lt;/a&gt;, and I wanted the same workflow there too. So I kept trying to bridge the gap.&lt;/p&gt;

&lt;p&gt;First, I built an &lt;a href="https://github.com/shinpr/sub-agents-mcp" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt; in August 2025 that let any MCP-compatible tool — Codex, Cursor, whatever — define and spawn sub-agents through a standard protocol. It worked, but MCP added a layer of indirection that wasn't there in Claude Code's native sub-agents.&lt;/p&gt;

&lt;p&gt;Then in December 2025, Codex &lt;a href="https://community.openai.com/t/skills-for-codex-experimental-support-starting-today/1369367" rel="noopener noreferrer"&gt;shipped experimental Agent Skills support&lt;/a&gt;. I saw an opening and built &lt;a href="https://github.com/shinpr/sub-agents-skills" rel="noopener noreferrer"&gt;sub-agents-skills&lt;/a&gt; — cross-LLM sub-agent orchestration packaged as Agent Skills, routing tasks to Codex, Claude Code, Cursor, or Gemini. Closer, but still not native sub-agents.&lt;/p&gt;

&lt;p&gt;Through all of this, my main development stayed on Claude Code. The context separation and the small context windows of the time made it the clear choice for serious work. Codex filled a supporting role — I used it for skills refinement and as an objective reviewer on complex implementations, a fresh set of eyes from a different LLM.&lt;/p&gt;

&lt;p&gt;I don't use hooks extensively — I prefer keeping tasks small and baking quality gates into the completion criteria themselves. So what I was really waiting for was native sub-agent support in Codex, which would let the full orchestration workflow run without workarounds.&lt;/p&gt;

&lt;p&gt;On March 16, 2026, Codex CLI &lt;a href="https://developers.openai.com/codex/subagents" rel="noopener noreferrer"&gt;shipped sub-agent support&lt;/a&gt;. During pre-release validation, I noticed something encouraging: Codex followed the workflow stopping points more strictly than expected. If the behavior stabilizes, it could be a viable primary development tool, not just a supporting one.&lt;/p&gt;

&lt;p&gt;The port took almost no effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "Near-Zero Migration" Actually Looks Like
&lt;/h2&gt;

&lt;p&gt;When I say "the same framework," I mean it. The core architecture didn't change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Request
    ↓
requirement-analyzer → scale determination [STOP for confirmation]
    ↓
technical-designer → Design Doc
    ↓
document-reviewer [STOP for approval]
    ↓
work-planner → phased task breakdown [STOP]
    ↓
task-decomposer → atomic task files
    ↓
Per-task 4-step cycle:
  task-executor → escalation check → quality-fixer → git commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;22 sub-agents. 26 skills. The same stopping points, the same quality gates, the same TDD enforcement.&lt;/p&gt;

&lt;p&gt;What changed was the &lt;strong&gt;container format&lt;/strong&gt;, not the content:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Codex CLI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent definitions&lt;/td&gt;
&lt;td&gt;Markdown with YAML frontmatter (&lt;code&gt;agents/*.md&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;TOML files (&lt;code&gt;.codex/agents/*.toml&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skills location&lt;/td&gt;
&lt;td&gt;&lt;code&gt;skills/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.agents/skills/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool declarations&lt;/td&gt;
&lt;td&gt;Explicit in frontmatter (&lt;code&gt;tools: Read, Grep, Glob...&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Not needed (inferred from sandbox mode)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skill references&lt;/td&gt;
&lt;td&gt;Comma-separated names&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;[[skills.config]]&lt;/code&gt; arrays&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Config directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.claude/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.codex/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That's it. The agent instructions — the actual substance of what each agent knows and does — are the same. The workflow logic is the same. The quality criteria are the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Worked: Design Decisions That Paid Off
&lt;/h2&gt;

&lt;p&gt;It worked for a surprisingly simple reason — three choices I made early on:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Natural Language as the Interface Layer
&lt;/h3&gt;

&lt;p&gt;Every sub-agent's behavior is defined in natural language instructions, not in platform-specific tool calls. The requirement-analyzer isn't wired to Claude Code's &lt;code&gt;Agent&lt;/code&gt; tool or Codex's &lt;code&gt;spawn_agent&lt;/code&gt; — it follows a written protocol: "Extract task type, determine scale (1-2 files = Small, 3-5 = Medium, 6+ = Large), identify ADR necessity, output structured JSON."&lt;/p&gt;

&lt;p&gt;This means the instructions work on any LLM-powered agent system that can read text and follow procedures. In practice, that turned out to be enough. The framework is fundamentally &lt;strong&gt;a set of well-written job descriptions&lt;/strong&gt;, not a set of API integrations.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Context Separation as Architecture
&lt;/h3&gt;

&lt;p&gt;The core insight from the &lt;a href="https://dev.to/shinpr/zero-context-exhaustion-building-production-ready-ai-coding-teams-with-claude-code-sub-agents-31b"&gt;original article&lt;/a&gt; still applies: each agent runs in a fresh context without inheriting bias from previous steps. The document-reviewer doesn't know what the technical-designer was "thinking" — it just reviews the output. The investigator explores without confirmation bias from whoever reported the bug.&lt;/p&gt;

&lt;p&gt;This isn't a Claude Code feature or a Codex feature. It's an &lt;strong&gt;architectural pattern&lt;/strong&gt; that happens to be implementable on both platforms once they support sub-agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Structured Handoffs Over Shared State
&lt;/h3&gt;

&lt;p&gt;Agents communicate through artifacts (documents, JSON outputs, task files), not through shared memory or conversation threading. The technical-designer writes a Design Doc. The work-planner reads that Design Doc. Neither needs to know which platform spawned the other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;docs/
├── prd/          # PRD artifacts
├── adr/          # Architecture decision records
├── design/       # Design documents
├── plans/        # Work plans
│   └── tasks/    # Atomic task files (1 commit each)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file-based protocol turned out to be surprisingly platform-agnostic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Framework in Action
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/shinpr/codex-workflows" rel="noopener noreferrer"&gt;codex-workflows&lt;/a&gt; ships as an npm package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx codex-workflows &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This drops the full agent and skill infrastructure into your project. From there, you invoke recipe skills that orchestrate the sub-agents:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Recipe&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$recipe-implement&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full lifecycle: requirements → design → implementation → quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$recipe-design&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Requirements → design documents only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$recipe-build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Execute pre-planned tasks autonomously&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$recipe-diagnose&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Problem investigation → root cause → solutions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$recipe-front-build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;React/TypeScript implementation with frontend-specific agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$recipe-fullstack-implement&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cross-layer features with layer-aware task routing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each recipe automatically loads the right foundational skills (coding standards, testing principles, documentation criteria) and spawns the right sequence of agents with the right stopping points.&lt;/p&gt;

&lt;p&gt;Here's what a real session looks like. I ran &lt;code&gt;$recipe-implement Add a login screen with email/password and a simple auth API&lt;/code&gt; in Codex CLI against a fresh project with placeholder files:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Requirement analysis — the first mandatory stop:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;• Spawned Plato [requirement-analyzer] (gpt-5.4-mini medium)

• Updated requirement analysis is now confirmed:
  - Scope: email/password login form, local mock auth abstraction,
    hardcoded success credentials demo@example.com / password123,
    inline success message only
  - Route: fullstack
  - Scale: medium
  - ADR: not required

  Please confirm this analysis and answer these three questions:
  1. Should the auth API be a real HTTP endpoint, or is a local/mock
     API abstraction enough?
  2. What credentials should succeed initially?
  3. On successful login, should it only show success, navigate
     somewhere, or persist auth state too?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow stops and waits. No implementation starts until I confirm scope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Parallel design — backend and frontend at the same time:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;• Spawned Volta [technical-designer] (gpt-5.4-mini medium)
  └ Create a backend Design Doc...

• Spawned Pasteur [technical-designer-frontend] (gpt-5.4-mini medium)
  └ Create a frontend Design Doc...

• Spawned Epicurus [document-reviewer] (gpt-5.4-mini medium)
  └ Review login-backend-design.md...

• Spawned Bohr [document-reviewer] (gpt-5.4-mini medium)
  └ Review login-frontend-design.md...

• Spawned Euclid [design-sync] (gpt-5.4-mini medium)
  └ Verify consistency between Design Docs...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five agents in parallel: two designers, two reviewers, one cross-layer sync checker. Each running in its own fresh context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Design gate — another mandatory stop:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;• The design gate is now clean enough to stop for approval.

  - Backend design: approved
  - Frontend design: approved
  - Cross-layer sync: NO_CONFLICTS

  Aligned contract:
  - Success: { ok: true }
  - Failure: { ok: false, error }
  - Inline success copy is UI-owned, not backend-owned

  Please approve the design docs so I can move to
  acceptance-test generation and the work plan.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Autonomous execution after batch approval:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;› batch approval

• Spawned Ohm [task-decomposer] (gpt-5.4-mini medium)

• Verification passed:
  - npm test
  - npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After batch approval, the framework decomposed the work plan into tasks and executed them autonomously — no more stopping points until the quality gates pass.&lt;/p&gt;

&lt;p&gt;The whole flow from &lt;code&gt;$recipe-implement&lt;/code&gt; to green tests took one session. The same flow, the same stopping points, the same agent roles that I've been running on Claude Code for months.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;The framework is open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Codex CLI version&lt;/strong&gt;: &lt;a href="https://github.com/shinpr/codex-workflows" rel="noopener noreferrer"&gt;codex-workflows&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code version&lt;/strong&gt;: &lt;a href="https://github.com/shinpr/claude-code-workflows" rel="noopener noreferrer"&gt;claude-code-workflows&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're already using the Claude Code version, the Codex version follows the same patterns. If you're new to both, pick whichever CLI you're already using — the workflow knowledge transfers either way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx codex-workflows &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;The whole port changed config file formats and directory conventions. The agent instructions — the part that actually matters — didn't need a single edit. That's the thing I'd want to know if I were deciding whether to invest time in workflow design for AI coding tools.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you've been running sub-agent workflows with either Claude Code or Codex CLI, I'd be curious how your setup compares. What worked? What broke?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Letting LLMs Jump — and Then Verifying Ruthlessly</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Thu, 12 Feb 2026 13:35:03 +0000</pubDate>
      <link>https://dev.to/shinpr/letting-llms-jump-and-then-verifying-ruthlessly-1mj0</link>
      <guid>https://dev.to/shinpr/letting-llms-jump-and-then-verifying-ruthlessly-1mj0</guid>
      <description>&lt;h2&gt;
  
  
  The "First Plausible Answer" Problem
&lt;/h2&gt;

&lt;p&gt;You've probably seen this: you ask an LLM to investigate a bug, and it latches onto the first plausible explanation. It confidently proposes a fix before thoroughly exploring alternatives. Sometimes it works. Often it doesn't—and you're left debugging the debugger.&lt;/p&gt;

&lt;p&gt;I ran into this repeatedly in my personal projects. The LLM would find &lt;em&gt;something&lt;/em&gt; that looked like the cause, stop investigating, and immediately suggest a solution. When the codebase was small, this worked fine. As it grew, I started getting fixes that didn't actually fix anything.&lt;/p&gt;

&lt;p&gt;This is not for small scripts or simple bugs.&lt;/p&gt;

&lt;p&gt;I only started needing this once my codebase grew large enough&lt;br&gt;
that "just try a fix" stopped working.&lt;/p&gt;

&lt;p&gt;The root issue? &lt;strong&gt;How I was defining the task's purpose.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Planning works well when the problem is understood.&lt;/p&gt;

&lt;p&gt;But when the problem itself is unclear,&lt;br&gt;
planning alone is not enough.&lt;/p&gt;

&lt;p&gt;This article focuses on those cases.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Factor That Made the Difference: Purpose
&lt;/h2&gt;

&lt;p&gt;When delegating tasks to LLMs, two factors affect execution accuracy: &lt;strong&gt;Context&lt;/strong&gt; (staying within ~70% of the context window) and &lt;strong&gt;Purpose&lt;/strong&gt; (how you define the task's goal).&lt;/p&gt;

&lt;p&gt;Context management matters, but this article focuses on the second factor—because that's where I was getting it wrong.&lt;/p&gt;

&lt;p&gt;Where you set the task's goal matters more than you might think. The purpose you define determines the task granularity, and the right granularity depends on your codebase complexity.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Real Example: Bug Investigation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Old Approach
&lt;/h3&gt;

&lt;p&gt;A single session handling "Investigation → Solution Proposal → Verification," followed by a separate review session.&lt;/p&gt;

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

&lt;p&gt;My original goal was simple: "propose a solution" and "review it objectively."&lt;/p&gt;

&lt;p&gt;Originally, I'd just have the LLM investigate, propose a fix, and implement it directly. But as the codebase grew, I started getting solutions that didn't actually work. So I added a review step—opening a fresh session to check the proposal with clean context.&lt;/p&gt;

&lt;p&gt;This worked for about 60-70% of problems, but occasionally even this approach couldn't reach the root cause no matter how many iterations.&lt;/p&gt;

&lt;p&gt;Here's what I changed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Problem Structuring&lt;/strong&gt;: Structure my instructions upfront to make them easier for LLMs to parse in later steps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investigation&lt;/strong&gt;: Conduct comprehensive investigation and report results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification&lt;/strong&gt;: If there's uncertainty in the report, perform additional verification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution Derivation&lt;/strong&gt;: Receive investigation and verification results, then derive solutions&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;By setting &lt;strong&gt;"investigation" as the purpose&lt;/strong&gt;, the model stopped jumping to the first candidate and instead collected information from multiple angles.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementation Example
&lt;/h2&gt;

&lt;p&gt;This setup is probably overkill for small scripts. I only started doing this after my codebase crossed a certain complexity threshold.&lt;/p&gt;

&lt;p&gt;Here's how I structured the diagnosis workflow using Claude Code's slash commands and sub-agents. Full implementation is available at &lt;a href="https://github.com/shinpr/claude-code-workflows" rel="noopener noreferrer"&gt;github.com/shinpr/claude-code-workflows&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Main Command (diagnose.md)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Investigate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;problem,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;verify&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;findings,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;derive&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;solutions"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gs"&gt;**Command Context**&lt;/span&gt;: Diagnosis flow to identify root cause and present solutions

Target problem: $ARGUMENTS

&lt;span class="gu"&gt;## Step 0: Problem Structuring (Before investigator invocation)&lt;/span&gt;

&lt;span class="gu"&gt;### 0.1 Problem Type Determination&lt;/span&gt;

| Type | Criteria |
|------|----------|
| Change Failure | Indicates some change occurred before the problem appeared |
| New Discovery | No relation to changes is indicated |

&lt;span class="gu"&gt;### 0.2 Information Supplementation for Change Failures&lt;/span&gt;

If the following are unclear, &lt;span class="gs"&gt;**ask with AskUserQuestion**&lt;/span&gt; before proceeding:
&lt;span class="p"&gt;-&lt;/span&gt; What was changed (cause change)
&lt;span class="p"&gt;-&lt;/span&gt; What broke (affected area)
&lt;span class="p"&gt;-&lt;/span&gt; Relationship between both (shared components, etc.)

&lt;span class="gu"&gt;## Diagnosis Flow Overview&lt;/span&gt;

The goal of investigation is not to propose solutions.
It is to eliminate wrong explanations.

&lt;span class="gs"&gt;**Context Separation**&lt;/span&gt;: Pass only structured JSON output to each step.
Each step starts fresh with the JSON data only.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Sub-agent: Investigator
&lt;/h3&gt;

&lt;p&gt;Think of the Investigator as a junior engineer whose only job is to gather facts—not to be clever. Its purpose is explicitly limited to &lt;strong&gt;evidence collection only&lt;/strong&gt;—no solutions:&lt;/p&gt;

&lt;p&gt;This is one concrete implementation.&lt;br&gt;
The important part is the separation of purpose—not the specific tooling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Output Scope&lt;/span&gt;

This agent outputs &lt;span class="gs"&gt;**evidence matrix and factual observations only**&lt;/span&gt;.
Solution derivation is out of scope for this agent.

&lt;span class="gu"&gt;## Core Responsibilities&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; &lt;span class="gs"&gt;**Cross-check multiple sources**&lt;/span&gt; - Don't rely on a single source
&lt;span class="p"&gt;2.&lt;/span&gt; &lt;span class="gs"&gt;**Search external info (WebSearch)**&lt;/span&gt; - Official docs, Stack Overflow, GitHub Issues
&lt;span class="p"&gt;3.&lt;/span&gt; &lt;span class="gs"&gt;**List hypotheses and trace causes**&lt;/span&gt; - Multiple candidates, not just the first one
&lt;span class="p"&gt;4.&lt;/span&gt; &lt;span class="gs"&gt;**Identify impact scope**&lt;/span&gt; - Where else might this pattern exist?
&lt;span class="p"&gt;5.&lt;/span&gt; &lt;span class="gs"&gt;**Disclose blind spots**&lt;/span&gt; - Honestly report areas that could not be investigated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key output structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hypotheses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"H1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hypothesis description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"causeCategory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"typo|logic_error|missing_constraint|design_gap|external_factor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"causalChain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Phenomenon"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"→ Direct cause"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"→ Root cause"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"supportingEvidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"contradictingEvidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"unexploredAspects"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Unverified aspects"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"comparisonAnalysis"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"normalImplementation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Path to working implementation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"failingImplementation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Path to problematic implementation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"keyDifferences"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Differences"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sub-agent: Verifier
&lt;/h3&gt;

&lt;p&gt;The Verifier plays the annoying senior reviewer who assumes everything is wrong. It actively seeks refutation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Core Responsibilities&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; &lt;span class="gs"&gt;**Cross-check multiple sources**&lt;/span&gt; - Explore information sources not covered
&lt;span class="p"&gt;2.&lt;/span&gt; &lt;span class="gs"&gt;**Generate alternative hypotheses**&lt;/span&gt; - What else could explain this?
&lt;span class="p"&gt;3.&lt;/span&gt; &lt;span class="gs"&gt;**Play devil's advocate**&lt;/span&gt; - Assume "the investigation results are wrong"
&lt;span class="p"&gt;4.&lt;/span&gt; &lt;span class="gs"&gt;**Pick the hypothesis with fewest holes**&lt;/span&gt; - Not "most evidence," but "least refuted"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sub-agent: Solver
&lt;/h3&gt;

&lt;p&gt;The Solver is the engineer who actually has to ship something. Only after verification does it derive solutions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Output Scope&lt;/span&gt;

This agent outputs &lt;span class="gs"&gt;**solution derivation and recommendation presentation**&lt;/span&gt;.
Trust the given conclusion and proceed directly to solution derivation.

&lt;span class="gu"&gt;## Core Responsibilities&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; &lt;span class="gs"&gt;**Multiple solution generation**&lt;/span&gt; - At least 3 different approaches
&lt;span class="p"&gt;2.&lt;/span&gt; &lt;span class="gs"&gt;**Tradeoff analysis**&lt;/span&gt; - Cost, risk, impact scope, maintainability
&lt;span class="p"&gt;3.&lt;/span&gt; &lt;span class="gs"&gt;**Recommendation selection**&lt;/span&gt; - Optimal solution with selection rationale
&lt;span class="p"&gt;4.&lt;/span&gt; &lt;span class="gs"&gt;**Implementation steps presentation**&lt;/span&gt; - Concrete, actionable steps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Practical Guidelines
&lt;/h2&gt;

&lt;p&gt;When designing LLM tasks, I now check two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Purpose Clarity&lt;/strong&gt; - "Don't create tasks with unclear purposes"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context Efficiency&lt;/strong&gt; - Can it be completed in one session with sufficient information? (Ideally using 60-70% of working space)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I don't blindly split tasks into smaller pieces. Instead, I consider ROI and break down from larger tasks only when necessary.&lt;/p&gt;

&lt;p&gt;By explicitly separating "investigation" from "solution," you prevent the model from rushing to conclusions before it has gathered sufficient evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Lesson I Learned the Hard Way
&lt;/h2&gt;

&lt;p&gt;Early on, I made the Verifier run every single time. The problem? Even when the investigation was clearly off track, the Verifier would dutifully try to verify nonsense.&lt;/p&gt;

&lt;p&gt;That's when I realized: &lt;strong&gt;you need a quality gate between steps&lt;/strong&gt;, not just separation.&lt;/p&gt;

&lt;p&gt;Now I have a checkpoint between Investigation and Verification. If the investigation output doesn't meet basic quality criteria (missing comparison analysis, shallow causal chains, etc.), it loops back instead of wasting cycles on verification.&lt;/p&gt;

&lt;p&gt;I also added Step 0 (Problem Structuring) to help the LLM understand my intent better before diving in. These two changes—quality gates and upfront structuring—made the whole pipeline actually usable.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Design Integration Checkpoints Before Letting LLMs Code</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Wed, 04 Feb 2026 13:23:55 +0000</pubDate>
      <link>https://dev.to/shinpr/design-integration-checkpoints-before-letting-llms-code-edo</link>
      <guid>https://dev.to/shinpr/design-integration-checkpoints-before-letting-llms-code-edo</guid>
      <description>&lt;p&gt;Once you stop trying to control AI generation and start designing verification, you immediately hit the next problem: integration.&lt;br&gt;
And this is where most AI-generated systems actually break.&lt;/p&gt;

&lt;p&gt;Everything works.&lt;br&gt;
Until it doesn't.&lt;/p&gt;

&lt;p&gt;Each layer looks correct in isolation.&lt;br&gt;
Tests pass.&lt;br&gt;
Types line up.&lt;/p&gt;

&lt;p&gt;And then the system breaks where those layers meet.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why "Everything Works" Until It Doesn't
&lt;/h2&gt;

&lt;p&gt;This is a verification problem, not an implementation problem.&lt;br&gt;
When you build systems layer by layer, integration happens very late.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Layer-by-layer development
Phase 1: Data layer ────────────────✓
Phase 2: Service layer ─────────────✓
Phase 3: API layer ────────────────✓
Phase 4: UI layer ─────────────────✓
Phase 5: Integration ── 💥 breaks here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer is implemented in isolation.&lt;br&gt;
So you don't actually know if everything connects correctly until the end.&lt;/p&gt;

&lt;p&gt;This problem becomes much worse with AI-generated code.&lt;/p&gt;

&lt;p&gt;LLMs don't hold the entire system in mind at once.&lt;br&gt;
They optimize locally, based on the current context — and they often miss hidden contracts between layers.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Painful Integration Bug That "Worked"
&lt;/h2&gt;

&lt;p&gt;One of the most painful bugs I faced didn't involve crashes or errors.&lt;/p&gt;

&lt;p&gt;The AI chatbot worked.&lt;/p&gt;

&lt;p&gt;It returned responses.&lt;br&gt;
Logs looked normal.&lt;br&gt;
Nothing failed.&lt;/p&gt;

&lt;p&gt;But when we tested it in the real environment, the answers were subtly — but consistently — wrong.&lt;/p&gt;
&lt;h3&gt;
  
  
  What actually went wrong
&lt;/h3&gt;

&lt;p&gt;The root cause wasn't a single mistake, but a combination of issues across layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mock implementations silently left in place&lt;/li&gt;
&lt;li&gt;LLM fallbacks that prioritized "returning something" instead of failing fast&lt;/li&gt;
&lt;li&gt;Duplicate logic across layers, created while implementing each layer separately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common thread? I wasn't tracking what else might break.&lt;/p&gt;

&lt;p&gt;Each layer looked correct in isolation.&lt;br&gt;
Tests passed.&lt;br&gt;
No alerts fired.&lt;/p&gt;

&lt;p&gt;Because the system always returned some response, it created a false sense of confidence.&lt;br&gt;
We didn't notice the problem immediately — and by the time we did, identifying the real cause across layers was extremely difficult.&lt;/p&gt;

&lt;p&gt;Bugs that silently "work" are far more dangerous than bugs that crash.&lt;/p&gt;
&lt;h2&gt;
  
  
  Make Integration Explicit
&lt;/h2&gt;

&lt;p&gt;I now spend about five minutes defining integration checkpoints.&lt;br&gt;
Not documentation. Just verification.&lt;/p&gt;

&lt;p&gt;The goal is simple: define where things must connect, and how I'll know they actually do.&lt;/p&gt;

&lt;p&gt;Now, before implementation, I write a very small design note.&lt;/p&gt;

&lt;p&gt;Not a formal design document.&lt;br&gt;
Nothing formal.&lt;/p&gt;

&lt;p&gt;Just a checklist that answers two questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What parts of the system are affected?&lt;/li&gt;
&lt;li&gt;Where do things need to integrate — and how do I verify it?&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Step 1: List What's Affected
&lt;/h3&gt;

&lt;p&gt;First, I write down what is directly or indirectly impacted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Change&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add image generation feature&lt;/span&gt;

&lt;span class="na"&gt;Direct impact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;infrastructure/image/functions.ts&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;application/services/queryClassificationService.ts&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;application/services/imageGenerationService.ts&lt;/span&gt;

&lt;span class="na"&gt;Indirect impact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;conversationService.ts (function calling flow)&lt;/span&gt;

&lt;span class="na"&gt;No impact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;existing text generation services&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;other function handlers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This immediately clarifies the blast radius.&lt;/p&gt;

&lt;p&gt;I don't aim for perfection —&lt;br&gt;
I just want to avoid being surprised later.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Define Integration Checkpoints
&lt;/h3&gt;

&lt;p&gt;Next, I decide where integration must be verified and how.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Integration point 1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Function selection&lt;/span&gt;
&lt;span class="na"&gt;Location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ConversationService.generateContentWithFunctionCalling&lt;/span&gt;

&lt;span class="na"&gt;How to verify&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;1. Send a request asking for an image&lt;/span&gt;
  &lt;span class="s"&gt;2. Confirm query classification returns `image_generation`&lt;/span&gt;
  &lt;span class="s"&gt;3. Confirm the correct function is selected in logs&lt;/span&gt;

&lt;span class="na"&gt;Expected result&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Log shows: Executing function&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;generateImage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And another one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Integration point 2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Image generation and posting&lt;/span&gt;
&lt;span class="na"&gt;Location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ImageGenerationService → MessagingClient.uploadFile&lt;/span&gt;

&lt;span class="na"&gt;How to verify&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;1. Image data is returned from the image client&lt;/span&gt;
  &lt;span class="s"&gt;2. The file is posted to the chat thread&lt;/span&gt;

&lt;span class="na"&gt;Expected result&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Image appears in the chat&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I know exactly what "working" means.&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Works (Especially with AI)
&lt;/h2&gt;

&lt;p&gt;When I give this to an LLM, it changes how implementation happens.&lt;/p&gt;

&lt;p&gt;Instead of "build this feature," it's more like:&lt;br&gt;
"Connect A to B. Here's how we'll know it works."&lt;/p&gt;

&lt;p&gt;This also pairs well with building features end-to-end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feature-based development
Feature A: Data → Service → API → UI → Verify
Feature B: Data → Service → API → UI → Verify
Feature C: Data → Service → API → UI → Verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each feature is fully integrated before moving on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;Before this habit, integration bugs often cost me hours.&lt;/p&gt;

&lt;p&gt;After introducing these small design notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI-generated code still has small issues&lt;/li&gt;
&lt;li&gt;But features no longer completely break at integration&lt;/li&gt;
&lt;li&gt;Unexpected behavior is caught much earlier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Five minutes of thinking up front easily saves hours of debugging later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who This Is For
&lt;/h2&gt;

&lt;p&gt;This approach works well if you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use AI coding tools&lt;/li&gt;
&lt;li&gt;Build layered architectures&lt;/li&gt;
&lt;li&gt;Want fast feedback instead of perfect design docs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not about writing more documentation.&lt;br&gt;
It's just about making integration explicit before code is written.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;AI tools are incredibly powerful — but they optimize locally.&lt;/p&gt;

&lt;p&gt;If we don't define integration points explicitly, we end up debugging systems that look correct but behave incorrectly.&lt;/p&gt;

&lt;p&gt;A small design checklist has made a huge difference for me.&lt;/p&gt;

&lt;p&gt;Hope this saves you some painful debugging.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Planning Is the Real Superpower of Agentic Coding</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Mon, 26 Jan 2026 12:24:31 +0000</pubDate>
      <link>https://dev.to/shinpr/planning-is-the-real-superpower-of-agentic-coding-1imm</link>
      <guid>https://dev.to/shinpr/planning-is-the-real-superpower-of-agentic-coding-1imm</guid>
      <description>&lt;p&gt;I see this pattern constantly: someone gives an LLM a task, it starts executing immediately, and halfway through you realize it's building the wrong thing. Or it gets stuck in a loop. Or it produces something that technically works but doesn't fit the existing codebase at all.&lt;/p&gt;

&lt;p&gt;The instinct is to write better prompts. More detail. More constraints. More examples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The actual fix is simpler: make it plan before it executes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Research shows that separating planning from execution dramatically improves task success rates—by as much as 33% in complex scenarios.&lt;/p&gt;

&lt;p&gt;In earlier articles, I wrote about why &lt;a href="https://dev.to/shinpr/why-llms-are-bad-at-first-try-and-great-at-verification-4kcf"&gt;LLMs struggle with first attempts&lt;/a&gt; and why &lt;a href="https://dev.to/shinpr/stop-putting-everything-in-agentsmd-22bl"&gt;overloading AGENTS.md&lt;/a&gt; is often a symptom of that misunderstanding. This article focuses on what actually fixes that.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why "Just Execute" Fails
&lt;/h2&gt;

&lt;p&gt;This took me longer to figure out than I'd like to admit. When you ask an LLM to directly implement something, you're asking it to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand the requirements&lt;/li&gt;
&lt;li&gt;Analyze the existing codebase&lt;/li&gt;
&lt;li&gt;Design an approach&lt;/li&gt;
&lt;li&gt;Evaluate trade-offs&lt;/li&gt;
&lt;li&gt;Decompose into steps&lt;/li&gt;
&lt;li&gt;Execute each step&lt;/li&gt;
&lt;li&gt;Verify results&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All in one shot. With one context. Using the same cognitive load throughout.&lt;/p&gt;

&lt;p&gt;Even powerful LLMs struggle with this. Not because they lack capability, but because &lt;strong&gt;long-horizon planning is fundamentally hard in a step-by-step mode.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Plan-Execute Architecture
&lt;/h2&gt;

&lt;p&gt;Research on LLM agents has consistently shown that separating planning and execution yields better results.&lt;/p&gt;

&lt;p&gt;The reasons:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benefit&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Explicit long-term planning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Even strong LLMs struggle with multi-step reasoning when taking actions one at a time. Explicit planning forces consideration of the full path.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You can use a powerful model for planning and a lighter model for execution—or even different specialized models per phase.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Efficiency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each execution step doesn't need to reason through the entire conversation history. It just needs to execute against the plan.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What matters here: &lt;strong&gt;the plan becomes an artifact&lt;/strong&gt;, and the execution becomes &lt;em&gt;verification against that artifact&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you've read about why LLMs are better at verification than first-shot generation, this should sound familiar. Creating a plan first converts the execution task from "generate good code" to "implement according to this plan"—a much clearer, more verifiable objective.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Full Workflow
&lt;/h2&gt;

&lt;p&gt;The complete picture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Preparation
    │
    ▼
Step 2: Design (Agree on Direction)
    │
    ▼
Step 3: Work Planning  ← The Most Important Step
    │
    ▼
Step 4: Execution
    │
    ▼
Step 5: Verification &amp;amp; Feedback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll walk through each step, but Step 3 is where the magic happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Preparation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: Clarify &lt;em&gt;what&lt;/em&gt; you want to achieve, not &lt;em&gt;how&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a ticket, issue, or todo document stating the goal in plain language&lt;/li&gt;
&lt;li&gt;Point the LLM to AGENTS.md (or CLAUDE.md, depending on your tool) and relevant context files&lt;/li&gt;
&lt;li&gt;Don't jump into implementation details yet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is about setting the stage, not solving the problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Design (Agree on Direction)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: Align on the approach before any code gets written.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't Let It Start Coding Immediately
&lt;/h3&gt;

&lt;p&gt;Instead of "implement this feature," say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Before implementing, present a step-by-step plan for how you would approach this."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Review the Plan
&lt;/h3&gt;

&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contradictions with existing architecture&lt;/li&gt;
&lt;li&gt;Simpler alternatives the LLM missed&lt;/li&gt;
&lt;li&gt;Misunderstandings of the requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this stage, you're agreeing on &lt;strong&gt;what to build&lt;/strong&gt; and &lt;strong&gt;why this approach&lt;/strong&gt;. The &lt;strong&gt;how&lt;/strong&gt; and &lt;strong&gt;in what order&lt;/strong&gt; come in Step 3.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Work Planning (The Most Important Step)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;This section is dense. But the payoff is proportional—the more carefully you plan, the smoother execution becomes.&lt;/p&gt;

&lt;p&gt;For small tasks, you don't need all of this. See "Scaling to Task Size" at the end.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: Convert the design into executable work units with clear completion criteria.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Step Matters Most
&lt;/h3&gt;

&lt;p&gt;Research shows that decomposing complex tasks into subtasks significantly improves LLM success rates. Step-by-step decomposition produces more accurate results than direct generation.&lt;/p&gt;

&lt;p&gt;But there's another reason: &lt;strong&gt;the work plan is an artifact&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When the plan exists, the execution task transforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before: "Build this feature" (generation)&lt;/li&gt;
&lt;li&gt;After: "Implement according to this plan" (verification)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the same principle from Article 1. Creating a plan first means execution becomes verification—and LLMs are better at verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Work Planning Includes
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Task decomposition&lt;/strong&gt;: Break the design into executable units&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency mapping&lt;/strong&gt;: Define order and dependencies between tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Completion criteria&lt;/strong&gt;: What does "done" mean for each task?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkpoint design&lt;/strong&gt;: When do we get external feedback?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Perspectives to Consider
&lt;/h3&gt;

&lt;p&gt;I'll be honest: I learned most of these the hard way. Plans would fall apart mid-implementation, and only later did I realize I'd skipped something obvious in hindsight.&lt;/p&gt;

&lt;p&gt;These aren't meant to be followed rigidly for every task. Think of them as a mental checklist. You don't need to get all of these right—if even one of these perspectives changes your plan, it's doing its job.&lt;/p&gt;




&lt;h4&gt;
  
  
  Perspective 1: Current State Analysis
&lt;/h4&gt;

&lt;p&gt;Understand what exists before planning changes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is this code's actual responsibility?&lt;/li&gt;
&lt;li&gt;Which parts are essential business logic vs. technical constraints?&lt;/li&gt;
&lt;li&gt;What benefits and limitations does the current design provide?&lt;/li&gt;
&lt;li&gt;What implicit dependencies or assumptions aren't obvious from the code?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skipping this leads to plans that don't fit the existing codebase.&lt;/p&gt;




&lt;h4&gt;
  
  
  Perspective 2: Strategy Selection
&lt;/h4&gt;

&lt;p&gt;Consider how to approach the transition from current to desired state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Research options:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for similar patterns in your tech stack&lt;/li&gt;
&lt;li&gt;Check how comparable projects solved this&lt;/li&gt;
&lt;li&gt;Review OSS implementations, articles, documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common strategy patterns:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strangler Pattern&lt;/strong&gt;: Gradual replacement, incremental migration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Facade Pattern&lt;/strong&gt;: Hide complexity behind unified interface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature-Driven&lt;/strong&gt;: Vertical slices, user-value first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Foundation-Driven&lt;/strong&gt;: Build stable base first, then features on top&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key isn't applying patterns dogmatically—it's consciously choosing an approach instead of stumbling into one.&lt;/p&gt;




&lt;h4&gt;
  
  
  Perspective 3: Risk Assessment
&lt;/h4&gt;

&lt;p&gt;Evaluate what could go wrong with your chosen strategy.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Risk Type&lt;/th&gt;
&lt;th&gt;Considerations&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Technical&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Impact on existing systems, data integrity, performance degradation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Operational&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Service availability, deployment downtime, rollback procedures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Project&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Schedule delays, learning curve, team coordination&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Skipping risk assessment leads to expensive surprises mid-implementation.&lt;/p&gt;




&lt;h4&gt;
  
  
  Perspective 4: Constraints
&lt;/h4&gt;

&lt;p&gt;Identify hard limits before committing to a strategy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Technical&lt;/strong&gt;: Library compatibility, resource capacity, performance requirements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeline&lt;/strong&gt;: Deadlines, milestones, external dependencies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt;: Team availability, skill gaps, budget&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business&lt;/strong&gt;: Time-to-market, customer impact, regulations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strategy that ignores constraints isn't executable.&lt;/p&gt;




&lt;h4&gt;
  
  
  Perspective 5: Completion Levels
&lt;/h4&gt;

&lt;p&gt;Define what "done" means for each task—this is critical.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L1: Functional verification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Works as user-facing feature&lt;/td&gt;
&lt;td&gt;Search actually returns results&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L2: Test verification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;New tests added and passing&lt;/td&gt;
&lt;td&gt;Type definition tests pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L3: Build verification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No compilation errors&lt;/td&gt;
&lt;td&gt;Interface definition complete&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Priority: L1 &amp;gt; L2 &amp;gt; L3&lt;/strong&gt;. Whenever possible, verify at L1 (actually works in practice).&lt;/p&gt;

&lt;p&gt;This directly maps to "external feedback" from the previous articles. Defining completion levels upfront ensures you get external verification at each checkpoint.&lt;/p&gt;




&lt;h4&gt;
  
  
  Perspective 6: Integration Points
&lt;/h4&gt;

&lt;p&gt;Define when to verify things work together.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Integration Point&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Feature-driven&lt;/td&gt;
&lt;td&gt;When users can actually use the feature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Foundation-driven&lt;/td&gt;
&lt;td&gt;When all layers are complete and E2E tests pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strangler pattern&lt;/td&gt;
&lt;td&gt;At each old-to-new system cutover&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Without defined integration points, you end up with "it all works individually but doesn't work together."&lt;/p&gt;




&lt;h3&gt;
  
  
  Task Decomposition Principles
&lt;/h3&gt;

&lt;p&gt;After considering the perspectives, break down into concrete tasks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executable granularity:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each task = one meaningful commit&lt;/li&gt;
&lt;li&gt;Clear completion criteria&lt;/li&gt;
&lt;li&gt;Explicit dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Minimize dependencies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maximum 2 levels deep (A→B→C is okay, A→B→C→D needs redesign)&lt;/li&gt;
&lt;li&gt;Tasks with 3+ chained dependencies should be split&lt;/li&gt;
&lt;li&gt;Each task should ideally provide independent value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Build quality in:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't make "write tests" a separate task—include testing in the implementation task&lt;/li&gt;
&lt;li&gt;Tag each task with its completion level (L1/L2/L3, though in practice L1 is almost always what you want)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Work Planning Anti-Patterns
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Anti-Pattern&lt;/th&gt;
&lt;th&gt;Consequence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Skip current-state analysis&lt;/td&gt;
&lt;td&gt;Plan doesn't fit codebase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ignore risks&lt;/td&gt;
&lt;td&gt;Expensive surprises mid-implementation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ignore constraints&lt;/td&gt;
&lt;td&gt;Plan isn't executable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Over-detail&lt;/td&gt;
&lt;td&gt;Lose flexibility, waste planning time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Undefined completion criteria&lt;/td&gt;
&lt;td&gt;"Done" is ambiguous, verification impossible&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Scaling to Task Size
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Not every task needs full work planning.&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;Scale&lt;/th&gt;
&lt;th&gt;Planning Depth&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Small (1-2 hours)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Verbal/mental notes or simple TODO list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Medium (1 day to 1 week)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Written work plan, but abbreviated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Large (1+ weeks)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full work plan covering all perspectives&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a typo fix, you don't need a work plan. For a multi-week refactor, you absolutely do.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Execution
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: Implement according to the work plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Work in Small Steps
&lt;/h3&gt;

&lt;p&gt;Follow the plan. One task at a time. One file, one function at a time where appropriate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types-First
&lt;/h3&gt;

&lt;p&gt;When adding new functionality, define interfaces and types before implementing logic. Type definitions become guardrails that help both you and the LLM stay on track.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Changes Everything
&lt;/h3&gt;

&lt;p&gt;With a work plan in place, execution becomes &lt;em&gt;verification&lt;/em&gt;. The LLM isn't guessing what to build—it's checking whether the implementation matches the plan.&lt;/p&gt;

&lt;p&gt;If you need to deviate from the plan, &lt;strong&gt;update the plan first&lt;/strong&gt;, then continue implementation. Don't let plan and implementation drift apart.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Verification &amp;amp; Feedback
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: Verify results and externalize learnings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feedback Format
&lt;/h3&gt;

&lt;p&gt;When something goes wrong, don't just paste an error. Include the intent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ Just the error
[error log]

✅ Intent + error
Goal: Redirect to dashboard after authentication
Issue: Following error occurs
[error log]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without intent, the LLM optimizes for "remove the error." With intent, it optimizes for "achieve the goal."&lt;/p&gt;

&lt;h3&gt;
  
  
  Externalize Learnings
&lt;/h3&gt;

&lt;p&gt;If you find yourself explaining the same thing twice, it's time to write it down.&lt;/p&gt;

&lt;p&gt;I covered this in detail in the previous article—where to put rules, what to write, and how to verify they work. The short version: write root causes, not specific incidents, and put them where they'll actually be read.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referencing Skills and Rules
&lt;/h2&gt;

&lt;p&gt;One common failure mode: you reference a skill or rule file, but the LLM just reads it and moves on without actually applying it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Write "see AGENTS.md"&lt;/td&gt;
&lt;td&gt;It's already loaded—redundant reference adds noise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;@file.md&lt;/code&gt; only&lt;/td&gt;
&lt;td&gt;LLM reads it, then continues. Reading ≠ applying&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Please reference X"&lt;/td&gt;
&lt;td&gt;References it minimally, doesn't apply the content&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Solution: Blocking References
&lt;/h3&gt;

&lt;p&gt;Make the reference a task with verification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Required Rules [MANDATORY - MUST BE ACTIVE]&lt;/span&gt;

&lt;span class="gs"&gt;**LOADING PROTOCOL:**&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; STEP 1: CHECK if &lt;span class="sb"&gt;`.agents/skills/coding-rules/SKILL.md`&lt;/span&gt; is active
&lt;span class="p"&gt;-&lt;/span&gt; STEP 2: If NOT active → Execute BLOCKING READ
&lt;span class="p"&gt;-&lt;/span&gt; STEP 3: CONFIRM skill active before proceeding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why This Works
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Element&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Action verbs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"CHECK", "READ", "CONFIRM"—not just "reference"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;STEP numbers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Forces sequence, can't skip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Before proceeding&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Blocking—must complete before continuing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;If NOT active&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Conditional—skips if already loaded (efficiency)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This maps to the task clarity principle: "check if loaded → load if needed → confirm → proceed" is far clearer than "please reference this file."&lt;/p&gt;




&lt;h2&gt;
  
  
  How This Connects to the Theory
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Connection to LLM Characteristics&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Step 1: Preparation&lt;/td&gt;
&lt;td&gt;Task clarification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step 2: Design&lt;/td&gt;
&lt;td&gt;Artifact-first (design doc is an artifact)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step 3: Work Planning&lt;/td&gt;
&lt;td&gt;Artifact-first (plan is an artifact) + external feedback design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step 4: Execution&lt;/td&gt;
&lt;td&gt;Transform "generation" into "verification against plan"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step 5: Verification&lt;/td&gt;
&lt;td&gt;Obtain external feedback + externalize learnings&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The work plan created in Step 3 converts Step 4 from "generate from scratch" to "verify against specification." This is the key mechanism for improving accuracy.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Research
&lt;/h2&gt;

&lt;p&gt;The practices in this article aren't just workflow opinions—they're backed by research on how LLM agents perform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ADaPT (Prasad et al., NAACL 2024)&lt;/strong&gt;: Separating planning and execution, with dynamic subtask decomposition when needed, achieved up to 33% higher success rates than baselines (28.3% on ALFWorld, 27% on WebShop, 33% on TextCraft).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plan-and-Execute (LangChain)&lt;/strong&gt;: Explicit long-term planning enables handling complex tasks that even powerful LLMs struggle with in step-by-step mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-Layer Task Decomposition (PMC, 2024)&lt;/strong&gt;: Step-by-step models generate more accurate results than direct generation—task decomposition directly improves output quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task Decomposition (Amazon Science, 2025)&lt;/strong&gt;: With proper task decomposition, smaller specialized models can match the performance of larger general models.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Don't let it execute immediately.&lt;/strong&gt; Ask for a plan first. Even just "present your approach step-by-step before implementing" makes a significant difference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Work Planning is the superpower.&lt;/strong&gt; A plan is an artifact. Having it converts execution from generation to verification—and LLMs are better at verification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define completion criteria.&lt;/strong&gt; L1 (works as feature) &amp;gt; L2 (tests pass) &amp;gt; L3 (builds). Know what "done" means before starting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale to task size.&lt;/strong&gt; Small task = mental note. Large task = full work plan. Don't over-plan trivial work, don't under-plan complex work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update plan before deviating.&lt;/strong&gt; If implementation needs to differ from the plan, update the plan first. Drift kills the verification benefit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Include intent with errors.&lt;/strong&gt; "Goal + error" beats "just error." The LLM should know what you're trying to achieve, not just what went wrong.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prasad, A., et al. (2024). "ADaPT: As-Needed Decomposition and Planning with Language Models." NAACL 2024 Findings. arXiv:2311.05772&lt;/li&gt;
&lt;li&gt;Wang, L., et al. (2023). "Plan-and-Solve Prompting: Improving Zero-Shot Chain-of-Thought Reasoning by Large Language Models." ACL 2023.&lt;/li&gt;
&lt;li&gt;LangChain. "Plan-and-Execute Agents." &lt;a href="https://blog.langchain.com/planning-agents/" rel="noopener noreferrer"&gt;https://blog.langchain.com/planning-agents/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>softwareengineering</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Stop Guessing If Your Prompt Is Better</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Thu, 22 Jan 2026 13:52:50 +0000</pubDate>
      <link>https://dev.to/shinpr/stop-guessing-if-your-prompt-is-better-5amb</link>
      <guid>https://dev.to/shinpr/stop-guessing-if-your-prompt-is-better-5amb</guid>
      <description>&lt;p&gt;You rewrote your prompt. The output looks different. But is it actually &lt;em&gt;better&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Most of us have been there — reading prompt engineering best practices, tweaking instructions, and hoping the changes help. But without comparison, you're just guessing.&lt;/p&gt;

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

&lt;p&gt;When you improve a prompt, you typically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the new version&lt;/li&gt;
&lt;li&gt;Look at the output&lt;/li&gt;
&lt;li&gt;Think "yeah, this seems better"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But you're comparing against your memory of the old output. Different runs produce different results anyway. How do you know the improvement came from your changes and not just LLM variance?&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/shinpr/rashomon" rel="noopener noreferrer"&gt;rashomon&lt;/a&gt; is a Claude Code plugin that focuses on one practical question: &lt;strong&gt;"Did my instruction change actually affect the result?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It analyzes your prompt, generates an optimized version, runs both in isolated environments, and compares the actual results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Example
&lt;/h2&gt;

&lt;p&gt;I ran this prompt through rashomon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add logging to track function calling usage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A reasonable instruction. But vague.&lt;/p&gt;
&lt;h3&gt;
  
  
  What rashomon detected
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vague instructions&lt;/td&gt;
&lt;td&gt;What, where, and why to log are unclear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No output format&lt;/td&gt;
&lt;td&gt;Log structure not specified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing context&lt;/td&gt;
&lt;td&gt;No project architecture information&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  The optimized prompt
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Context

This is a Slack bot using Google Gemini API with function calling. 
The project uses a shared `logger` utility with structured logging.
Function calling flows through:
1. `GeminiService.executeWithRetry()` - detects function calls
2. `FunctionHandler.handleFunctionCall()` - executes them

## Task

Add logging to track function calling usage for analytics and debugging.

## Requirements

At Function Call Detection (GeminiService):
- Function name(s) detected
- Number of function calls in response

At Function Execution (FunctionHandler):
- Parameters passed (sanitized - exclude sensitive data)
- Execution duration
- Result status (success/failure)

## Output Format

logger.info('Function call detected', {
  functionName: 'executeWithRetry',
  detectedFunctions: ['searchNotionPages'],
  functionCallCount: 1
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  What changed
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Original&lt;/th&gt;
&lt;th&gt;Optimized&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Logging Scope&lt;/td&gt;
&lt;td&gt;1 stage (execution only)&lt;/td&gt;
&lt;td&gt;2 stages (detection + execution)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parameter Sanitization&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Passwords, tokens, secrets redacted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Files Modified&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The original prompt &lt;em&gt;looked&lt;/em&gt; reasonable, but led the agent to log at only one point. The optimized version covered both detection and execution — with security considerations the original didn't address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Classification: Structural Improvement&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  About Variance
&lt;/h2&gt;

&lt;p&gt;Not every difference is an improvement. rashomon distinguishes between structural gains and mere variance.&lt;/p&gt;

&lt;p&gt;I tried to create a Variance example — a prompt so clear that optimization wouldn't matter. I couldn't. In practice, the same vague prompt sometimes works beautifully, sometimes completely misses the point.&lt;/p&gt;

&lt;p&gt;rashomon just makes that inconsistency visible.&lt;/p&gt;
&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Requires &lt;a href="https://claude.ai/code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude
/plugin marketplace add shinpr/rashomon
/plugin &lt;span class="nb"&gt;install &lt;/span&gt;rashomon@rashomon
&lt;span class="c"&gt;# Restart session&lt;/span&gt;
/rashomon Your prompt here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/shinpr" rel="noopener noreferrer"&gt;
        shinpr
      &lt;/a&gt; / &lt;a href="https://github.com/shinpr/rashomon" rel="noopener noreferrer"&gt;
        rashomon
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Compare, improve, and verify prompt changes with evidence — not vibes.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/shinpr/rashomon/assets/rashomon-banner.jpg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fshinpr%2Frashomon%2Fassets%2Frashomon-banner.jpg" width="600" alt="Rashomon"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://claude.ai/code" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/77c3fac949481ce7960e41b57da074d377eb159a42c6cf4694cf225ddcada391/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436c61756465253230436f64652d506c7567696e2d707572706c65" alt="Claude Code"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/shinpr/rashomon/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d6bc2b26794002c24d023acaab01b6dbb953c57ab9cb80ba5b8aa2f2bd5de99a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c7565" alt="License"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;See what actually changes when you improve your prompts — not just different wording.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why rashomon?&lt;/h2&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Inspired by the &lt;em&gt;Rashomon effect&lt;/em&gt; — the idea that the same event can produce different outcomes depending on perspective
rashomon makes those differences explicit and comparable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Spending too much time on trial-and-error with prompts?&lt;/li&gt;
&lt;li&gt;Read best practices but not sure how they apply to your case?&lt;/li&gt;
&lt;li&gt;Want proof that your changes actually made things better?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;rashomon&lt;/strong&gt; analyzes, improves, and compares prompts—so you can see what &lt;em&gt;actually&lt;/em&gt; changed, and whether it matters.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Who Is This For?&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;rashomon is designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers using Claude Code daily&lt;/li&gt;
&lt;li&gt;Teams iterating on complex prompts (coding, analysis, writing)&lt;/li&gt;
&lt;li&gt;Anyone who wants &lt;strong&gt;evidence&lt;/strong&gt;, not vibes, when improving prompts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not ideal if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don't use git&lt;/li&gt;
&lt;li&gt;You want one-shot prompt rewriting without comparison&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Example&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;/rashomon Write a function to sort an array
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;What You Get&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;1. Detected Issues&lt;/strong&gt;&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;- BP-002&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/shinpr/rashomon" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





</description>
      <category>ai</category>
      <category>promptengineering</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stop Putting Everything in AGENTS.md</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Mon, 19 Jan 2026 14:13:49 +0000</pubDate>
      <link>https://dev.to/shinpr/stop-putting-everything-in-agentsmd-22bl</link>
      <guid>https://dev.to/shinpr/stop-putting-everything-in-agentsmd-22bl</guid>
      <description>&lt;p&gt;If you're using Agentic Coding and find yourself explaining the same thing to the LLM over and over, you have a learning externalization problem.&lt;/p&gt;

&lt;p&gt;The fix seems obvious: write it down in AGENTS.md (or CLAUDE.md, depending on your tool) and never explain it again.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This article uses "AGENTS.md" as the generic term for root instruction files. Claude Code uses CLAUDE.md, Codex uses AGENTS.md, and other tools have their own conventions. The principles apply regardless of the specific filename.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But here's what actually happens—you keep adding rules, AGENTS.md grows to 200+ lines, and somehow the LLM still ignores half of what you wrote.&lt;/p&gt;

&lt;p&gt;This article is about how to actually make your rules stick: &lt;strong&gt;where&lt;/strong&gt; to write them, &lt;strong&gt;what&lt;/strong&gt; to write, and how to verify they work.&lt;/p&gt;




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

&lt;p&gt;LLMs don't learn across sessions. Every conversation starts fresh. This means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You explain something once&lt;/li&gt;
&lt;li&gt;It works&lt;/li&gt;
&lt;li&gt;Next session, you explain it again&lt;/li&gt;
&lt;li&gt;And again&lt;/li&gt;
&lt;li&gt;Eventually you get frustrated&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The solution is to externalize your learnings into rules. But most people do this wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Common Mistakes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mistake&lt;/th&gt;
&lt;th&gt;What Happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Put everything in AGENTS.md&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;It bloats, becomes noise, important rules get buried&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Put everything in code comments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LLM doesn't load them into context unless you explicitly reference the file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Don't write it down at all&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You repeat yourself forever&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The thing is, &lt;strong&gt;where you write a rule determines whether the LLM actually follows it.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Where to Write Rules
&lt;/h2&gt;

&lt;p&gt;Not all rules belong in the same place. A simple decision tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;When is this rule needed?
│
├─ Always, on every task → AGENTS.md
│
├─ When working on a specific feature → Design Doc
│
├─ When using a specific technology → Rule file (skill)
│
└─ When performing a specific task type → Task guidelines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: "Skills" are modular rule files used in tools like Codex and Claude Code. They allow you to inject context-specific rules only when relevant. If your tool doesn't have this concept, think of them as separate rule files you reference when needed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Task guidelines" refers to rules that apply only during specific operations—like code review, migration, or content generation. Some call these "task rules" or "task-specific constraints."&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Full Picture
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Destination&lt;/th&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;When Applied&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AGENTS.md&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All tasks&lt;/td&gt;
&lt;td&gt;Always&lt;/td&gt;
&lt;td&gt;Approval flows, stop conditions, project principles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rule files (skills)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Specific technology area&lt;/td&gt;
&lt;td&gt;When using that tech&lt;/td&gt;
&lt;td&gt;Type conventions, error handling patterns, function size limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Task guidelines&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Specific task type&lt;/td&gt;
&lt;td&gt;When doing that task&lt;/td&gt;
&lt;td&gt;Subagent usage rules, review procedures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Design docs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Specific feature&lt;/td&gt;
&lt;td&gt;When developing that feature&lt;/td&gt;
&lt;td&gt;Feature requirements, API specs, security constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code comments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Specific code location&lt;/td&gt;
&lt;td&gt;When modifying that code&lt;/td&gt;
&lt;td&gt;Implementation rationale, gotchas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Key Question
&lt;/h3&gt;

&lt;p&gt;Ask yourself: &lt;strong&gt;"Is this needed on &lt;em&gt;every&lt;/em&gt; task in this project?"&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Yes&lt;/strong&gt; → AGENTS.md&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No&lt;/strong&gt; → Put it closer to where it's needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps AGENTS.md lean (around 100 lines) and ensures task-specific rules don't create noise for unrelated work.&lt;/p&gt;

&lt;p&gt;You don't need to get this perfect from day one. Start with one thing: keep AGENTS.md small. That alone changes a lot.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Write
&lt;/h2&gt;

&lt;p&gt;This is the hard part. Most people write the wrong thing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Principle: Write Root Causes, Not Incidents
&lt;/h3&gt;

&lt;p&gt;When something goes wrong, the instinct is to document the specific incident. But this creates bias—the LLM over-fits to that one case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ Bad (specific incident)
"The getUser() function in UserService was missing null check"

✅ Good (root cause / system fix)
"Always null-check return values from external APIs"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first one only helps if the LLM encounters that exact function again. The second one prevents the entire &lt;em&gt;class&lt;/em&gt; of errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Specific Incident vs. Root Cause
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Specific Incident&lt;/th&gt;
&lt;th&gt;Root Cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Applies to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;That one location&lt;/td&gt;
&lt;td&gt;All similar cases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prevents recurrence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Weakly (same bug elsewhere)&lt;/td&gt;
&lt;td&gt;Strongly (operates as principle)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bias risk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High (overfitting)&lt;/td&gt;
&lt;td&gt;Low (generalizable)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Finding the Root Cause
&lt;/h3&gt;

&lt;p&gt;When you encounter an issue, ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Why did this mistake happen?&lt;/strong&gt; (direct cause)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why wasn't it prevented?&lt;/strong&gt; (system gap)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where else could this same mistake occur?&lt;/strong&gt; (scope)&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;Direct cause: &lt;code&gt;getUser()&lt;/code&gt; was missing null check&lt;/li&gt;
&lt;li&gt;System gap: We trusted external API return values without validation&lt;/li&gt;
&lt;li&gt;Scope: All external API calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ &lt;strong&gt;Rule to write&lt;/strong&gt;: "Always null-check return values from external APIs"&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Verify Rules Work
&lt;/h2&gt;

&lt;p&gt;This is the step most people skip—and it's critical.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Principle: Fix the System, Then Discard and Retry
&lt;/h3&gt;

&lt;p&gt;When you add or modify a rule in AGENTS.md or a skill file, you need to verify it actually works. The only way to do this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Add/modify the rule&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discard&lt;/strong&gt; the current artifact (or stash it in a branch)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start a new session&lt;/strong&gt; with the updated rules&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Re-run the same task&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; the issue doesn't recur
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Continue with existing artifact after rule change → ❌
Discard and restart with new rules → ✅
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why This Matters
&lt;/h3&gt;

&lt;p&gt;If you keep the existing artifact and just continue, you're still operating in a context polluted by the old system. The new rule might not get properly applied because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The existing artifact carries biases from before the rule existed&lt;/li&gt;
&lt;li&gt;The LLM might try to "reconcile" the new rule with existing work rather than applying it cleanly&lt;/li&gt;
&lt;li&gt;You can't tell if the rule actually works or if you just manually fixed the symptom&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Verification Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Modified the rule (AGENTS.md / skill file / task guideline)&lt;/li&gt;
&lt;li&gt;[ ] Discarded current artifact (or moved to a branch)&lt;/li&gt;
&lt;li&gt;[ ] Started new session with updated rules&lt;/li&gt;
&lt;li&gt;[ ] Re-ran the same task&lt;/li&gt;
&lt;li&gt;[ ] Confirmed the issue doesn't recur&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For small changes, you can stash instead of discard. The key is: &lt;strong&gt;test the system in isolation&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  When to Write Rules
&lt;/h2&gt;

&lt;p&gt;Not every issue deserves a rule. Some guidance:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Write a Rule?&lt;/th&gt;
&lt;th&gt;Rationale&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;You explained the same thing twice&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prevent the third time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encountered unexpected behavior&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Maybe&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Find root cause first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task completed successfully&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Maybe&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Retrospective—any generalizable insights?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Found a serious bug&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prevent recurrence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Warning Signs You're Over-Documenting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AGENTS.md exceeds &lt;strong&gt;100 lines&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A single rule file exceeds &lt;strong&gt;300 lines&lt;/strong&gt; (~1,500 tokens)&lt;/li&gt;
&lt;li&gt;Rules take more than 1 minute to read through&lt;/li&gt;
&lt;li&gt;You find yourself thinking "is this really needed every time?"&lt;/li&gt;
&lt;li&gt;Rules contradict each other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you see these signs, it's time to prune. &lt;strong&gt;Rule maintenance includes deletion.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Write Rules (Cheat Sheet)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This section is a reference.&lt;/strong&gt; You don't need to read it all now—come back when you're actually writing a rule. The rest of the article stands on its own.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1. Minimum Viable Length
&lt;/h3&gt;

&lt;p&gt;Context is precious. Same meaning, shorter expression. But don't sacrifice clarity for brevity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;❌ Verbose (38 chars)
If an error occurs, you must always log it

✅ Concise (20 chars)
All errors must be logged

❌ Too short (unclear)
Log errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. No Duplication
&lt;/h3&gt;

&lt;p&gt;Same content in multiple places wastes context and creates update drift.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;❌ Duplicated
&lt;span class="gh"&gt;# base.md&lt;/span&gt;
Standard error format: { success: false, error: string }

&lt;span class="gh"&gt;# api.md&lt;/span&gt;
Errors use { success: false, error: string } format

✅ Single source
&lt;span class="gh"&gt;# base.md&lt;/span&gt;
Standard error format: { success: false, error: string }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Measurable Criteria
&lt;/h3&gt;

&lt;p&gt;Vague instructions create interpretation variance. Use numbers and specific conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;✅ Measurable
&lt;span class="p"&gt;-&lt;/span&gt; Functions: max 30 lines
&lt;span class="p"&gt;-&lt;/span&gt; Cyclomatic complexity: max 10
&lt;span class="p"&gt;-&lt;/span&gt; Test coverage: min 80%

❌ Vague
&lt;span class="p"&gt;-&lt;/span&gt; Readable code
&lt;span class="p"&gt;-&lt;/span&gt; Sufficient testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Recommendations Over Prohibitions
&lt;/h3&gt;

&lt;p&gt;Banning things without alternatives leaves the LLM guessing. Show the right way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;✅ Recommendation + rationale
【State Management】
Recommended: Zustand or Context API
Reason: Global variables make testing difficult, state tracking complex
Avoid: window.globalState = { ... }

❌ Prohibition list
&lt;span class="p"&gt;-&lt;/span&gt; Don't use global variables
&lt;span class="p"&gt;-&lt;/span&gt; Don't store values on window
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Priority Order
&lt;/h3&gt;

&lt;p&gt;LLMs pay more attention to what comes first. Lead with the most important rules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Critical (Must Follow)&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; All APIs require JWT authentication
&lt;span class="p"&gt;2.&lt;/span&gt; Rate limit: 100 requests/minute

&lt;span class="gu"&gt;## Standard Specs&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Methods: Follow REST principles
&lt;span class="p"&gt;-&lt;/span&gt; Body: JSON format

&lt;span class="gu"&gt;## Edge Cases (Only When Applicable)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; File uploads may use multipart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Clear Scope Boundaries
&lt;/h3&gt;

&lt;p&gt;State what the rule covers—and what it doesn't.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Scope&lt;/span&gt;

&lt;span class="gu"&gt;### Applies To&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; REST API endpoints
&lt;span class="p"&gt;-&lt;/span&gt; GraphQL endpoints

&lt;span class="gu"&gt;### Does Not Apply To&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Static file serving
&lt;span class="p"&gt;-&lt;/span&gt; Health checks (/health)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Feedback Loop
&lt;/h2&gt;

&lt;p&gt;This is how it all fits together in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Working with LLM]
       │
       ├─ Issue occurs
       │      │
       │      ▼
       │  Find root cause (not just symptom)
       │      │
       │      ▼
       │  Decide where to write (AGENTS.md? Skill? Task guideline?)
       │      │
       │      ▼
       │  Write the rule
       │      │
       │      ▼
       │  Discard current work
       │      │
       │      ▼
       │  New session with updated rules
       │      │
       │      ▼
       │  Verify issue doesn't recur
       │
       ▼
[Continue working]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is to reach a state where &lt;strong&gt;you never explain the same thing twice&lt;/strong&gt;. Every explanation either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gets externalized into a rule, or&lt;/li&gt;
&lt;li&gt;Was truly a one-off that doesn't need capturing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Passing Feedback Correctly
&lt;/h2&gt;

&lt;p&gt;One more thing: when you give feedback to the LLM, don't just paste error logs. Include your &lt;em&gt;intent&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ Just the error
[Stack trace]

✅ Intent + error
Goal: Redirect to dashboard after user authentication
Issue: Following error occurred
[Stack trace]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without the intent, the LLM optimizes for "make the error go away." With the intent, it optimizes for "achieve the goal while resolving this error."&lt;/p&gt;

&lt;p&gt;These are very different things.&lt;/p&gt;




&lt;h2&gt;
  
  
  Anti-Pattern Summary
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Quick reference if you want to check your current practices:&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Anti-Pattern&lt;/th&gt;
&lt;th&gt;Reference&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Put everything in AGENTS.md&lt;/td&gt;
&lt;td&gt;→ "Where to Write Rules"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write specific incidents instead of root causes&lt;/td&gt;
&lt;td&gt;→ "What to Write"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Continue with old artifacts after changing rules&lt;/td&gt;
&lt;td&gt;→ "How to Verify Rules Work"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List only prohibitions without recommendations&lt;/td&gt;
&lt;td&gt;→ "How to Write Rules" #4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep explaining instead of writing it down&lt;/td&gt;
&lt;td&gt;→ "When to Write Rules"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AGENTS.md is not a dumping ground.&lt;/strong&gt; Only rules needed on &lt;em&gt;every&lt;/em&gt; task belong there. Everything else goes closer to where it's used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write root causes, not incidents.&lt;/strong&gt; "Null-check external API returns" beats "UserService.getUser() was missing null check."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test your rules.&lt;/strong&gt; After adding a rule, discard current work and re-run. If the issue recurs, the rule isn't working.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maintenance includes deletion.&lt;/strong&gt; If AGENTS.md is over 100 lines, you've probably over-documented. Prune ruthlessly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Explain twice, document once.&lt;/strong&gt; If you're explaining the same thing for a second time, stop and externalize it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you stop expecting rules alone to do the work, the real question becomes how to design the workflow around them. In practice, that starts with &lt;a href="https://dev.to/shinpr/planning-is-the-real-superpower-of-agentic-coding-1imm"&gt;planning—before execution ever begins&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Research
&lt;/h2&gt;

&lt;p&gt;The practices in this article are grounded in LLM research:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SALAM (Wang et al., 2023)&lt;/strong&gt;: LLM self-feedback is often inaccurate. Structured feedback from external agents (or externalized rules) is more effective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LEMA (An et al., 2023)&lt;/strong&gt;: Learning from mistakes (error → explanation → correction) improves LLM reasoning ability—but this requires explicit externalization of what was learned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feedback Loop for IaC (Palavalli et al., 2024)&lt;/strong&gt;: Feedback loop effectiveness decreases exponentially with each iteration and plateaus. This supports the "discard and restart" approach over endless iteration in the same context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reflexion (Shinn et al., 2023)&lt;/strong&gt;: Combining short-term memory (recent trajectory) with long-term memory (past experience) enables effective self-improvement. Externalized rules function as that long-term memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Wang, D., et al. (2023). "Learning from Mistakes via Cooperative Study Assistant for Large Language Models." arXiv:2305.13829&lt;/li&gt;
&lt;li&gt;An, S., et al. (2023). "Learning From Mistakes Makes LLM Better Reasoner." arXiv:2310.20689&lt;/li&gt;
&lt;li&gt;Palavalli, M. A., et al. (2024). "Using a Feedback Loop for LLM-based Infrastructure as Code Generation." arXiv:2411.19043&lt;/li&gt;
&lt;li&gt;Shinn, N., et al. (2023). "Reflexion: Language Agents with Verbal Reinforcement Learning." NeurIPS 2023.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>softwareengineering</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why LLMs Are Bad at "First Try" and Great at Verification</title>
      <dc:creator>Shinsuke KAGAWA</dc:creator>
      <pubDate>Mon, 12 Jan 2026 12:46:19 +0000</pubDate>
      <link>https://dev.to/shinpr/why-llms-are-bad-at-first-try-and-great-at-verification-4kcf</link>
      <guid>https://dev.to/shinpr/why-llms-are-bad-at-first-try-and-great-at-verification-4kcf</guid>
      <description>&lt;p&gt;I used to spend hours crafting the perfect prompt.&lt;br&gt;
Detailed instructions, examples, constraints—the works.&lt;/p&gt;

&lt;p&gt;And the AI would still add random features I never asked for.&lt;br&gt;
Or refactor code that was perfectly fine.&lt;br&gt;
Or skip steps it decided were "unnecessary."&lt;/p&gt;

&lt;p&gt;Eventually it clicked: I was fighting a losing battle.&lt;br&gt;
So I stopped trying to control generation and started focusing on verification.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Failure Patterns You've Probably Seen
&lt;/h2&gt;

&lt;p&gt;Before diving into why, these are the common anti-patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Giant Prompt Syndrome&lt;/strong&gt;: Cramming requirements, design, implementation, and improvement into a single prompt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overconfidence in Abstract Instructions&lt;/strong&gt;: Expecting "think carefully" or "be thorough" to actually improve quality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Invisible Loop&lt;/strong&gt;: Thinking you're iterating when you're actually spinning in circles within the same biased context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context Bloat&lt;/strong&gt;: Adding "just in case" information until the actually important instructions get buried&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of these sound familiar, you're in the right place.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Insight
&lt;/h2&gt;

&lt;p&gt;The claim is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLMs perform better at "verify and improve existing artifacts" than at "controlled first-time generation."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of trying to get the perfect output on the first attempt, you get better results by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Having the LLM produce &lt;em&gt;something&lt;/em&gt; first&lt;/li&gt;
&lt;li&gt;Then having it verify and improve that output&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is grounded in how LLMs actually process information.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Verification Works Better
&lt;/h2&gt;

&lt;p&gt;At first, I assumed better prompts would lead to better first-shot output. But after enough failures, the pattern became clear: there are three interconnected reasons why LLMs become "smarter" when they have something to work with.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. External Feedback Changes the Task
&lt;/h3&gt;

&lt;p&gt;When an artifact exists, the task fundamentally transforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Without artifact&lt;/strong&gt;: "Generate something good" (vague, open-ended)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;With artifact&lt;/strong&gt;: "Identify what's wrong with this and fix it" (specific, bounded)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second task has clearer success criteria. The LLM isn't guessing what "good" means—it can evaluate concrete issues against concrete output.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Position Bias (Lost in the Middle)
&lt;/h3&gt;

&lt;p&gt;Research has shown that LLMs exhibit a U-shaped attention pattern: they prioritize information at the &lt;strong&gt;beginning&lt;/strong&gt; and &lt;strong&gt;end&lt;/strong&gt; of their context window, while information in the &lt;strong&gt;middle&lt;/strong&gt; tends to get overlooked.&lt;/p&gt;

&lt;p&gt;When you feed an artifact as input to a new session, it naturally occupies a prominent position in the context. The LLM is literally forced to pay attention to it.&lt;/p&gt;

&lt;p&gt;This also explains why that really important instruction you buried in paragraph 5 of your mega-prompt keeps getting ignored.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Task Clarity Drives Performance
&lt;/h3&gt;

&lt;p&gt;"Improve this code" is a more concrete task than "write good code."&lt;/p&gt;

&lt;p&gt;The presence of an artifact provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A specific target for evaluation&lt;/li&gt;
&lt;li&gt;Clear boundaries for the scope of work&lt;/li&gt;
&lt;li&gt;Implicit success criteria (this one matters more than you'd think—"better than before" is much easier to verify than "good enough")&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Externality Spectrum
&lt;/h2&gt;

&lt;p&gt;What made the biggest difference for me was reviewing in a completely separate context.&lt;br&gt;
Once I stopped letting the generator review its own work, the blind spots became obvious.&lt;/p&gt;

&lt;p&gt;Not all feedback loops are created equal. Different approaches rank very differently in effectiveness:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5rubl6dcai7hiugd9h9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5rubl6dcai7hiugd9h9.png" alt="Verification methods effectiveness spectrum from external signals to self-introspection" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thing is, looping within the same session is fundamentally &lt;em&gt;internal&lt;/em&gt; feedback. The LLM is still operating within its original generation biases. Only by separating context do you get true "external" perspective.&lt;/p&gt;

&lt;p&gt;In short: if the context doesn't change, neither does the model's perspective.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Implications
&lt;/h2&gt;

&lt;p&gt;So what do you actually do with this?&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Artifact-First Workflow
&lt;/h3&gt;

&lt;p&gt;Stop trying to get everything right in one shot. Instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate Phase&lt;/strong&gt;: Get &lt;em&gt;something&lt;/em&gt; out, even if imperfect. Don't over-specify.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External Feedback&lt;/strong&gt;: Run the code, execute tests, use linters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification Phase&lt;/strong&gt; (new session): Feed the artifact + feedback to a fresh context
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Generation Session]
    │
    ├── Input: Requirements, constraints
    ├── Output: Artifact (code, design, etc.) + brief intent summary (1-3 lines)
    │
    ▼
[External Feedback]
    │
    ├── Code execution
    ├── Test execution
    ├── Linter/static analysis
    │
    ▼
[Verification Session]  ← Fresh context
    │
    ├── Input: Artifact + intent summary + feedback results
    ├── Output: Improved artifact
    │
    ▼
[Repeat or Complete]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Know When to Separate Sessions
&lt;/h3&gt;

&lt;p&gt;Session separation isn't always necessary. Use your judgment:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task Type&lt;/th&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small, localized fixes (typos, formatting)&lt;/td&gt;
&lt;td&gt;Same session is fine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clear error fixes (with stack trace)&lt;/td&gt;
&lt;td&gt;Same session works—external feedback (error log) exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Design changes, architecture revisions&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Separate sessions&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quality improvements, refactoring&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Separate sessions&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Direction changes, requirement pivots&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Separate sessions&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Rule of thumb&lt;/strong&gt;: If you're feeling "something isn't working," that's often a sign to start a fresh session. Your intuition about context pollution is usually right.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. What to Pass Between Sessions
&lt;/h3&gt;

&lt;p&gt;Not everything from the generation phase should go to the verification phase.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Content&lt;/th&gt;
&lt;th&gt;Should Pass?&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Full Chain-of-Thought log&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Verbose, becomes noise. Important info gets lost (position bias)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intent summary (1-3 lines)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Preserves the "why" compactly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Final decision + rationale&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Useful for debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rejected alternatives&lt;/td&gt;
&lt;td&gt;Maybe&lt;/td&gt;
&lt;td&gt;Only when specifically relevant&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The principle: &lt;strong&gt;Pass the "why," not the "how I thought about it."&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Designing Your AGENTS.md
&lt;/h2&gt;

&lt;p&gt;You don't need to redesign your AGENTS.md all at once. But understanding position bias changes how you think about what goes in it.&lt;/p&gt;

&lt;p&gt;This insight has direct implications for how you structure AGENTS.md (or whatever root instruction file you use—CLAUDE.md, cursorrules, etc.).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Position Bias Problem
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Context Window Position → Attention Weight

[AGENTS.md]            ← Start: HIGH attention
       ↓
[Middle instructions]  ← Middle: LOW attention (Lost in the Middle)
       ↓
[User prompt]          ← End: HIGH attention
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your AGENTS.md is bloated, the truly important principles get diluted. Adding more "just in case" actually makes everything weaker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design Principles
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AGENTS.md&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Core principles only. ~100 lines. What must be followed on &lt;em&gt;every&lt;/em&gt; task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Task-specific info&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inject via skills, command arguments, or reference files &lt;em&gt;when needed&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Why separate?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Context separation lets you compose optimal information for each task&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What Belongs in AGENTS.md
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Project purpose and domain&lt;/li&gt;
&lt;li&gt;Non-negotiable constraints (security, naming conventions)&lt;/li&gt;
&lt;li&gt;Tech stack overview&lt;/li&gt;
&lt;li&gt;Communication style&lt;/li&gt;
&lt;li&gt;Error handling behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What Doesn't Belong
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Individual feature specs&lt;/li&gt;
&lt;li&gt;API details&lt;/li&gt;
&lt;li&gt;Task-specific workflows&lt;/li&gt;
&lt;li&gt;Long code examples&lt;/li&gt;
&lt;li&gt;"Nice to have" information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Test&lt;/strong&gt;: Ask "Is this needed for &lt;em&gt;every&lt;/em&gt; task?" If no, it belongs elsewhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Human Role
&lt;/h2&gt;

&lt;p&gt;In Agentic Coding, you're not "using an LLM"—you're &lt;strong&gt;designing a system&lt;/strong&gt; where an LLM operates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your Responsibilities
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;th&gt;Concrete Actions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Design external feedback&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Decide which tests to run, which linters to use, what "success" means&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Determine session boundaries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Judge when to cut context, what carries over&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Define quality gates&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Separate automated checks from human review needs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Maintain AGENTS.md&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Keep core principles tight, prevent bloat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Articulate intent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Create or validate the "intent summary" that passes between sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Automation vs. Human Review
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good for automation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code execution, test execution&lt;/li&gt;
&lt;li&gt;Linters, formatters&lt;/li&gt;
&lt;li&gt;Type checking&lt;/li&gt;
&lt;li&gt;Security scans&lt;/li&gt;
&lt;li&gt;Applying formulaic fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Requires human review:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design decision validity&lt;/li&gt;
&lt;li&gt;Requirement alignment&lt;/li&gt;
&lt;li&gt;Session boundary judgment&lt;/li&gt;
&lt;li&gt;Trade-off decisions&lt;/li&gt;
&lt;li&gt;Validating the "why"&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  A Framework: Context Separation at Every Level
&lt;/h2&gt;

&lt;p&gt;It took me a while to realize this wasn't about writing better prompts—it was about where I drew the boundaries.&lt;/p&gt;

&lt;p&gt;You don't need to apply all of this rigidly. But when something feels off, one of these levels is usually the culprit:&lt;/p&gt;

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




&lt;h2&gt;
  
  
  The Research Behind This
&lt;/h2&gt;

&lt;p&gt;These aren't just opinions—they're grounded in LLM research:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-Refine (Madaan et al., 2023)&lt;/strong&gt;&lt;br&gt;
The generate → feedback → refine loop shows approximately 20% improvement over single-shot generation. Key insight: the improvement comes from the structured iteration, not from the model "trying harder."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lost in the Middle (Liu et al., 2023)&lt;/strong&gt;&lt;br&gt;
LLMs show U-shaped attention bias, heavily weighting the beginning and end of context while underweighting the middle. This explains why your carefully crafted instructions in paragraph 5 keep getting ignored.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLMs Cannot Self-Correct Reasoning Yet (Huang et al., 2023)&lt;/strong&gt;&lt;br&gt;
Without external feedback, self-correction doesn't work—and can actually make things worse. "Review your work" as an instruction has minimal effect; external signals (test failures, linter errors) are what drive actual improvement.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't optimize for first-shot perfection&lt;/strong&gt;. Get something out, then improve it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Session separation is real&lt;/strong&gt;. The same context that generated the artifact will struggle to objectively improve it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;External feedback is non-negotiable&lt;/strong&gt;. Tests, linters, execution results—these are what drive quality, not "think harder" prompts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep AGENTS.md lean&lt;/strong&gt;. Position bias means bloat actively hurts. If it's not needed for every task, move it out.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pass intent, not process&lt;/strong&gt;. Between sessions, transfer the "why" in 1-3 lines, not the full thought log.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You're a system designer&lt;/strong&gt;. Your job isn't to use the LLM—it's to design the workflow, feedback loops, and context boundaries that let it perform.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;This article focused on &lt;em&gt;why&lt;/em&gt; verification-oriented workflows outperform first-shot generation. In future articles, I'll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to structure work plans&lt;/strong&gt; that turn execution into verification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where to put rules&lt;/strong&gt; so they actually get followed (hint: not all in AGENTS.md)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've been struggling with inconsistent LLM output or finding that your detailed prompts underperform simpler ones, try restructuring around verification. The difference is often dramatic.&lt;/p&gt;

&lt;p&gt;What's your experience been? Did switching to a verification-first approach change anything for you?&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Madaan, A., et al. (2023). "Self-Refine: Iterative Refinement with Self-Feedback." arXiv:2303.17651&lt;/li&gt;
&lt;li&gt;Liu, N. F., et al. (2023). "Lost in the Middle: How Language Models Use Long Contexts." arXiv:2307.03172&lt;/li&gt;
&lt;li&gt;Huang, J., et al. (2023). "Large Language Models Cannot Self-Correct Reasoning Yet." ICLR 2024. arXiv:2310.01798&lt;/li&gt;
&lt;li&gt;Hsieh, C.-Y., et al. (2024). "Found in the Middle: Calibrating Positional Attention Bias Improves Long Context Utilization." ACL 2024 Findings. arXiv:2406.16008&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>softwareengineering</category>
      <category>promptengineering</category>
    </item>
  </channel>
</rss>
