<?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: Paul Horn</title>
    <description>The latest articles on DEV Community by Paul Horn (@paulhorn).</description>
    <link>https://dev.to/paulhorn</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%2F3959936%2F8a53d07d-2c55-428a-b1f2-030b2d7ddcaf.png</url>
      <title>DEV Community: Paul Horn</title>
      <link>https://dev.to/paulhorn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/paulhorn"/>
    <language>en</language>
    <item>
      <title>Designing an agent loop for coding</title>
      <dc:creator>Paul Horn</dc:creator>
      <pubDate>Mon, 13 Jul 2026 22:29:44 +0000</pubDate>
      <link>https://dev.to/paulhorn/designing-an-agent-loop-for-coding-1fmg</link>
      <guid>https://dev.to/paulhorn/designing-an-agent-loop-for-coding-1fmg</guid>
      <description>&lt;p&gt;A prompt tells a coding agent what to do once. Nearly everything that matters happens after the first result comes back wrong.&lt;/p&gt;

&lt;p&gt;Suppose you ask a coding agent to add CSV export to a reporting page. It reads the repository, edits a few files, runs a test, and reports success. The test fails, so you paste the error back in. The next version breaks the page, so you tell it to open the browser and look. The version after that works, but it also rewrote half the reporting module on the way.&lt;/p&gt;

&lt;p&gt;By the third round, you are the loop. You carry the evidence between attempts and you decide when the work is actually done.&lt;/p&gt;

&lt;p&gt;The question that interests me is how much of that can be written down precisely enough for the system to run it alone, and where it cannot be, so that the work comes back to a person instead of circling forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop outside the agent
&lt;/h2&gt;

&lt;p&gt;The word &lt;em&gt;loop&lt;/em&gt; is doing a lot of work in that last paragraph, so it helps to pull the senses apart. There is the ordinary loop inside a program. There is the internal cycle most agents already run on their own: look at the environment, pick an action, call a tool, look at the result, keep going.&lt;/p&gt;

&lt;p&gt;The one I care about here is a third loop, and it sits outside the model:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request → define goal → attempt → verify → decide&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If verification fails, the loop retries from the attempt while carrying the evidence forward.&lt;/p&gt;

&lt;p&gt;A recent preprint calls this a &lt;em&gt;loop specification&lt;/em&gt;: a trigger, a goal, some execution, a verification step, a rule for when to stop, and memory carried between rounds.&lt;a href="https://arxiv.org/abs/2607.00038" rel="noopener noreferrer"&gt;[1]&lt;/a&gt; The name is new but none of the parts are. Continuous integration has done a version of this for years. It runs when something happens, checks the result, records what it saw, and ends in a named state. The one thing an agent adds is a model that can rewrite its own plan between runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the condition for stopping
&lt;/h2&gt;

&lt;p&gt;“Implement CSV export” describes an activity. It does not describe when the activity is complete.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; A user can export the currently filtered report as a correctly encoded CSV file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check:&lt;/strong&gt; Run the export tests, verify the build, and inspect the diff for changes outside the reporting feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The split is the whole point. The goal is what should become true. The check is the evidence the loop will actually use to decide whether it did.&lt;/p&gt;

&lt;p&gt;Collapse the two and the agent ends up as its own author, tester, and judge. It will happily declare victory because the code looks reasonable, because a command exited zero, or because it has simply run out of ideas. None of those mean the feature works.&lt;/p&gt;

&lt;p&gt;It helps to treat verification as a ladder rather than a single gate. A self-report from the agent is the cheap bottom rung, and on its own it is worth almost nothing. A clean static check and a passing build tell you more. Targeted tests tell you more again, because they exercise the behavior you actually asked for. Running the real product surfaces the integration failures that no unit test was ever going to catch, and a separate review picks up the things the implementation agent has quietly trained itself to skip.&lt;/p&gt;

&lt;p&gt;Recent coding-agent research is pushing the same way. SWE-Cycle pulls apart environment setup, implementation, and test generation, then measures a sharp drop in performance once agents have to run the whole cycle themselves.&lt;a href="https://arxiv.org/abs/2605.13139" rel="noopener noreferrer"&gt;[2]&lt;/a&gt; SWE-Review bolts a separate reviewer onto a generate-review-revise loop and finds that structured review feedback makes later revisions better than one-shot generation does.&lt;a href="https://arxiv.org/abs/2607.06065" rel="noopener noreferrer"&gt;[3]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The verifier does not have to be another model. When a deterministic test can settle it, use the test. A model earns its place only when the check needs judgment: did the diff stay inside the feature, does the UI actually match what was asked, is this workaround a tradeoff you would accept.&lt;/p&gt;

&lt;h2&gt;
  
  
  The structure of a coding loop
&lt;/h2&gt;

&lt;p&gt;An attempt changes the environment, observation writes down what happened, and verification holds that evidence up against the goal. A failed check goes one of two ways: it either hands useful evidence to the next attempt, or it exits into a named terminal state.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Goal + check:&lt;/strong&gt; what done means, and the evidence that proves it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attempt:&lt;/strong&gt; the agent changes an isolated worktree&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observe:&lt;/strong&gt; collect the diff, test output, and runtime state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify:&lt;/strong&gt; hold the evidence against the check&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass:&lt;/strong&gt; verified work, yours to review, merge, or discard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stuck:&lt;/strong&gt; back to a person because the loop is blocked, out of budget, or repeating itself&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When the result is not ready, the loop returns to a new attempt with the failure evidence. The agent only occupies the Attempt step. The loop around it decides what counts as done, which evidence to trust, and when to stop.&lt;/p&gt;

&lt;p&gt;The agent is one box in this diagram. How the whole thing behaves depends just as much on the verifier, on the state you carry between attempts, on the retry policy, and on the rules that decide when the loop is allowed to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  A retry needs new information
&lt;/h2&gt;

&lt;p&gt;Feeding the agent the same prompt again is technically a loop. It is just not a loop that gets anywhere.&lt;/p&gt;

&lt;p&gt;Every failed attempt should hand something concrete to the next one: a failing assertion, a screenshot, a compiler error, a reviewer comment, or even a plain sentence about why the goal was missed. The next round should start from that, not from a fresh copy of the original request.&lt;/p&gt;

&lt;p&gt;Isolating attempts helps more than I expected it to. A fresh branch or worktree gives each attempt a clean starting point, keeps them comparable, and stops an abandoned approach from leaking into the one that follows. Run several attempts at once and each one needs its own workspace anyway. Then the loop can keep whichever result actually verified instead of trying to stitch half-compatible diffs together.&lt;/p&gt;

&lt;p&gt;Memory is worth being picky about. The loop needs the goal, the previous verdicts, the decisions that mattered, and the current state of the repository. It almost never needs the full transcript of every tool call. Keeping everything just makes the next round longer, not smarter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stopping is part of correctness
&lt;/h2&gt;

&lt;p&gt;Every loop needs explicit terminal states. At minimum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;success:&lt;/strong&gt; the check passed;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;blocked:&lt;/strong&gt; progress requires a person or missing external information;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;exhausted:&lt;/strong&gt; the attempt or cost limit was reached;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cancelled:&lt;/strong&gt; the user stopped the work;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;error:&lt;/strong&gt; the loop itself could not continue safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A cap on attempts is still worth having, but treat it as a safety bound and not as a definition of done. Work on iterative language-model systems suggests fixed iteration counts burn effort long after the output has stopped getting better. In one small non-coding experiment, a semantic stopping rule cut operational tokens by 38 percent at roughly the same measured quality.&lt;a href="https://arxiv.org/abs/2606.27009" rel="noopener noreferrer"&gt;[4]&lt;/a&gt; That number does not carry straight over to software, but the lesson behind it does: watch whether the loop is making progress, not just how many times it has gone around.&lt;/p&gt;

&lt;p&gt;The opposite failure is the loop that never hits a real bound at all. A July 2026 static-analysis study looked at 6,549 agent repositories and confirmed 68 likely infinite-agent-loop defects across 47 projects.&lt;a href="https://arxiv.org/abs/2607.01641" rel="noopener noreferrer"&gt;[5]&lt;/a&gt; In each case the loop kept reaching model calls, tools, retries, or handoffs without any stopping condition that covered the whole feedback path.&lt;/p&gt;

&lt;p&gt;For coding, a workable no-progress rule might trip when two attempts fail the same check for the same reason, when the diff stops changing in any meaningful way, or when the next step would need authority the agent was never given.&lt;/p&gt;

&lt;h2&gt;
  
  
  A loop should remain inspectable
&lt;/h2&gt;

&lt;p&gt;Handing more of the work to the machine does not shrink how much its internal state matters. It turns that state into about the only thing you can still supervise.&lt;/p&gt;

&lt;p&gt;While a loop runs, a developer should be able to answer plain questions about it. What is the goal right now? Which attempt is live? What changed? Which check is running? Why did the last attempt fail, and what happens if this one passes?&lt;/p&gt;

&lt;p&gt;That is the idea behind the new Cate Agent. For a code task, a read-only orchestrator sets the goal and the verification check. It can spin up one or more attempts in fresh Git worktrees. Per-attempt drivers launch coding-agent CLIs in real canvas terminals, and when an attempt finishes a separate verifier checks it. From there the orchestrator either takes a passing result or starts another round from the failure evidence. The finished work sits in a review state until you merge it, open it as a pull request, or throw it away.&lt;a href="https://github.com/0-AI-UG/cate/pull/423" rel="noopener noreferrer"&gt;[6]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reason the loop stays legible is that each part has a place you can point at. Attempts live in their own worktrees and terminals. Verification gets its own terminal. The result you kept stays visibly separate from the attempts you rejected. The canvas lays the process out as a workspace instead of flattening it into a single scrolling chat.&lt;/p&gt;

&lt;p&gt;So designing a loop turns out to be mostly structural work. You give a repeated process a shape: something concrete to satisfy, evidence to check it against, a little state to carry forward, limits that genuinely halt it, and an ending a person can still read. Getting the agent to run longer is almost beside the point.&lt;/p&gt;

&lt;p&gt;The model does the individual steps. Whether those steps add up to software you can actually ship is a property of the loop you built around it, and that part is still your job.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;S. Macedo, “Stop Hand-Holding Your Coding Agent: Engineering the Loops that Replace Step-by-Step Prompting” (2026). Used for the distinction between internal agent cycles and external loop specifications, and for the trigger, goal, verification, stopping, and memory structure. This is a recent preprint based partly on a hand-coded corpus of 50 public loops. &lt;a href="https://arxiv.org/abs/2607.00038" rel="noopener noreferrer"&gt;arxiv.org/abs/2607.00038&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;H. Guan et al., “SWE-Cycle: Benchmarking Code Agents across the Complete Issue Resolution Cycle” (2026). Used for the separation of environment reconstruction, implementation, verification-test generation, and complete-cycle execution. &lt;a href="https://arxiv.org/abs/2605.13139" rel="noopener noreferrer"&gt;arxiv.org/abs/2605.13139&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;R. Wang et al., “SWE-Review: Closing the Loop on Issue Resolution with Agentic Code Review” (2026). Used for the generate-review-revise architecture and reported value of structured reviewer feedback. This is a very recent preprint. &lt;a href="https://arxiv.org/abs/2607.06065" rel="noopener noreferrer"&gt;arxiv.org/abs/2607.06065&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;S. Shrivastava, “Semantic Early-Stopping for Iterative LLM Agent Loops” (2026). Used for the fixed-iteration critique and 38% operational-token result. The experiment covers 60 multi-hop QA questions, not coding tasks, so it is presented only as a stopping-policy example. &lt;a href="https://arxiv.org/abs/2606.27009" rel="noopener noreferrer"&gt;arxiv.org/abs/2606.27009&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;X. Hou et al., “When Agents Do Not Stop: Uncovering Infinite Agentic Loops in LLM Agents” (2026). Used for the definition and repository scan of infinite agentic loops. &lt;a href="https://arxiv.org/abs/2607.01641" rel="noopener noreferrer"&gt;arxiv.org/abs/2607.01641&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;0-AI-UG, “Cate Agent: job-card agent that drives coding CLIs in canvas worktrees” and the Cate Agent tool implementation (2026). Used for Cate’s goal, iteration, worktree, driver, verifier, and result-selection workflow. &lt;a href="https://github.com/0-AI-UG/cate/pull/423" rel="noopener noreferrer"&gt;github.com/0-AI-UG/cate/pull/423&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Cate is an open-source spatial workspace for coding agents, terminals, editors, browsers, and Git worktrees. &lt;a href="https://github.com/0-AI-UG/cate" rel="noopener noreferrer"&gt;Explore Cate on GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>coding</category>
    </item>
    <item>
      <title>10 nerdy GitHub repos I keep learning from</title>
      <dc:creator>Paul Horn</dc:creator>
      <pubDate>Sat, 30 May 2026 12:41:22 +0000</pubDate>
      <link>https://dev.to/paulhorn/10-nerdy-github-repos-i-keep-learning-from-3o2p</link>
      <guid>https://dev.to/paulhorn/10-nerdy-github-repos-i-keep-learning-from-3o2p</guid>
      <description>&lt;p&gt;I spend a lot of time browsing GitHub, not only to find tools, but to understand how good software is structured.&lt;/p&gt;

&lt;p&gt;This is not a “best repos of all time” list. More like a personal list of repos I keep coming back to because they teach something: architecture, performance, dev tooling, systems design, UI, or just taste.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. git/git
&lt;/h2&gt;

&lt;p&gt;Git is one of those tools everyone uses and almost nobody fully understands.&lt;/p&gt;

&lt;p&gt;The repo is worth studying because it is old, practical, and deeply battle-tested. There is a lot to learn from how a tool can stay relevant for decades without becoming trendy.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. torvalds/linux
&lt;/h2&gt;

&lt;p&gt;The Linux kernel is probably the most obvious nerd repo, but it still belongs here.&lt;/p&gt;

&lt;p&gt;Not because I understand every part of it. I do not. But reading around the repo gives you a feeling for scale, maintainership, hardware boundaries, naming, review culture, and the amount of discipline needed to keep something this large moving.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. sqlite/sqlite
&lt;/h2&gt;

&lt;p&gt;SQLite is one of my favorite examples of software that is quietly everywhere.&lt;/p&gt;

&lt;p&gt;Small surface area, huge impact. It is a good reminder that boring, reliable, embeddable software can be more impressive than most flashy infrastructure projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. redis/redis
&lt;/h2&gt;

&lt;p&gt;Redis is interesting because it feels simple from the outside, but the internals are full of careful tradeoffs.&lt;/p&gt;

&lt;p&gt;It is a good repo to study if you care about data structures, networking, memory, persistence, and how a small set of primitives can become infrastructure for a lot of other systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. curl/curl
&lt;/h2&gt;

&lt;p&gt;curl is a good example of a tool that does one thing extremely well and then survives basically every platform, edge case, and protocol mess humans have created.&lt;/p&gt;

&lt;p&gt;The repo is also interesting from a maintenance perspective. Supporting everything is not glamorous work, but it is real engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. neovim/neovim
&lt;/h2&gt;

&lt;p&gt;Neovim is interesting because it is both old-school and modern.&lt;/p&gt;

&lt;p&gt;It keeps the terminal/editor culture alive, but also has Lua, LSP, plugins, UIs, and a very active ecosystem around it. I like it as an example of how a project can modernize without losing its core identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. 0-AI-UG/cate
&lt;/h2&gt;

&lt;p&gt;Cate is one of my own projects, so this one is obviously biased.&lt;/p&gt;

&lt;p&gt;It is an open source infinite canvas IDE for coding workflows that do not fit well into one editor window anymore: terminals, agents, previews, files, logs, and notes all sitting on one zoomable workspace.&lt;/p&gt;

&lt;p&gt;The reason I include it here is not because it is done. It is still early. But it represents the kind of dev tool problem I care about most right now: not just better autocomplete or another chat box, but a better workspace for how coding is changing.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. tree-sitter/tree-sitter
&lt;/h2&gt;

&lt;p&gt;Tree-sitter is one of the more interesting dev tool building blocks.&lt;/p&gt;

&lt;p&gt;Fast incremental parsing sounds niche until you realize how many editor and code intelligence features depend on understanding code structure without running a full compiler pipeline.&lt;/p&gt;

&lt;p&gt;It is one of those projects that sits underneath the things developers use every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. wasm3/wasm3
&lt;/h2&gt;

&lt;p&gt;wasm3 is a WebAssembly interpreter, and it is just a fun repo to look at if you like low-level runtime stuff.&lt;/p&gt;

&lt;p&gt;WebAssembly often gets talked about in big platform terms, but repos like this make it feel much more concrete: instructions, execution, portability, constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. tinygrad/tinygrad
&lt;/h2&gt;

&lt;p&gt;tinygrad is interesting because it strips ML infrastructure down to something you can actually read and reason about.&lt;/p&gt;

&lt;p&gt;It is not “tiny” because the problem is simple. It is tiny because it tries to avoid hiding everything behind huge abstractions. That makes it a good repo to learn from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;The repos I like most usually have one thing in common:&lt;/p&gt;

&lt;p&gt;They are not just codebases. They are tools that changed how other people build.&lt;/p&gt;

&lt;p&gt;Some are huge, some are small, some are old, some are still moving fast. But all of them are worth studying if you care about software beyond just shipping the next feature.&lt;/p&gt;

&lt;p&gt;Also curious what repos other people keep coming back to. Especially the weird ones that are not on every standard “awesome GitHub repos” list.&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>programming</category>
      <category>vibecoding</category>
    </item>
  </channel>
</rss>
