{"id":11000,"date":"2026-11-09T16:26:33","date_gmt":"2026-11-09T16:26:33","guid":{"rendered":"https:\/\/www.hostinger.com\/blog\/?p=11000"},"modified":"2026-11-09T16:26:36","modified_gmt":"2026-11-09T16:26:36","slug":"hforge-coding-agents-feedback-loops","status":"publish","type":"post","link":"https:\/\/www.hostinger.com\/blog\/hforge-coding-agents-feedback-loops\/","title":{"rendered":"The two feedback loops behind running 10+ coding tasks at once"},"content":{"rendered":"<p class=\"wp-block-paragraph\">An AI agent finished fixing a file upload bug in the Hostinger dashboard, then suggested something nobody had asked for. Going back through the session, it noticed that a reviewer had left 17 comments on code style a linter could have caught, and proposed a lint rule.<\/p><p class=\"wp-block-paragraph\">Laurynas Bi&#269;kauskas, the AI engineer at Hostinger running the agent, went with it. The same day, the first of several rules from that idea fixed 378 components.<\/p><p class=\"wp-block-paragraph\">The agent was running <strong>hforge<\/strong>, a workflow skill Laurynas built for coding agents. These agents are now good enough that two things hold them back: a human checking their work, and the friction they work around, like slow tests or style rules no linter enforces yet.<\/p><p class=\"wp-block-paragraph\">To deal with both, hforge uses two feedback loops. Every change arrives with proof from a real build, so reviewers can trust it without retesting. And every task ends with a retrospective (retro) that looks for fixes to the environment, like that lint rule.<\/p><p class=\"wp-block-paragraph\">By Laurynas&rsquo; rough estimate, the two loops let him run about three times as many tasks at once, from four to as many as 12.<\/p><h2 class=\"wp-block-heading h-t-title-2\" id=\"h-how-hforge-runs-a-task\">How hforge runs a task<\/h2><p class=\"wp-block-paragraph\">Every task in hforge is called an effort, and it starts with planning. The agent asks about scope and product context, makes most of the technical calls itself, and writes it all down in a <strong>plan.md<\/strong>. The plan includes a destination, which lists the scenarios that should work when the effort is done.<\/p><p class=\"wp-block-paragraph\">Then three kinds of agents get to work:<\/p><ul class=\"wp-block-list\">\n<li><strong>The main chat.<\/strong> The only agent the human talks to. It never writes code. Instead, it hands out work and keeps an eye on GitHub for review comments, failing checks, and merges.<\/li>\n\n\n\n<li><strong>A worker per repository.<\/strong> It writes the change and opens the pull request (PR) as a draft.<\/li>\n\n\n\n<li><strong>A proof subagent per repository.<\/strong> It tests the change on the PR preview, a temporary deployment of that branch, and reports back to the worker.<\/li>\n<\/ul><p class=\"wp-block-paragraph\">Because the main chat only coordinates, its context stays small even when one effort opens five PRs. Bigger work splits into slices that can run in parallel sessions, and a small effort usually wraps up in about an hour.<\/p><p class=\"wp-block-paragraph\">Laurynas keeps updating hforge, too. In a single month, he merged 211 changes to it and the tooling around it.<\/p><p class=\"wp-block-paragraph\">The first version of hforge was a big command-line tool packed with rules about how to handle each step, and the rules mostly got in the agents&rsquo; way.<\/p><p class=\"wp-block-paragraph\">So Laurynas threw most of them out and kept plain Markdown instructions and one PR per repository. His reasoning was that today&rsquo;s models are smart enough to pick their own path, as long as they know the context and the scope.<\/p><p class=\"wp-block-paragraph\">The rule that survived the cleanup is that agents never merge. A human always makes that call.<\/p><p class=\"wp-block-paragraph\">The two feedback loops wrap around this flow. Proof runs between the worker and the proof subagent before a PR goes up for review, and the retro runs once the effort ends.<\/p><div class=\"wp-block-image\">\n<figure data-wp-context='{\"imageId\":\"6af34aa3aae54\"}' data-wp-interactive=\"core\/image\" data-wp-key=\"6af34aa3aae54\" class=\"aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" width=\"1920\" height=\"920\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-flow.png\/public\" alt=\"Diagram of an hforge task moving from the human to the main chat, a worker, a pull request, a reviewer, and a retrospective, with a proof loop between the worker and a proof subagent and a retro loop feeding fixes into the next task\" class=\"wp-image-11023\" srcset=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-flow.png\/w=1920,fit=scale-down 1920w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-flow.png\/w=300,fit=scale-down 300w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-flow.png\/w=1024,fit=scale-down 1024w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-flow.png\/w=768,fit=scale-down 768w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-flow.png\/w=1536,fit=scale-down 1536w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><button class=\"lightbox-trigger\" type=\"button\" aria-haspopup=\"dialog\" data-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\" data-wp-init=\"callbacks.initTriggerButton\" data-wp-on--click=\"actions.showLightbox\" data-wp-style--right=\"state.thisImage.buttonRight\" data-wp-style--top=\"state.thisImage.buttonTop\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\"><\/path>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div><h2 class=\"wp-block-heading h-t-title-2\" id=\"h-loop-1-making-agents-show-their-work\">Loop 1: making agents show their work<\/h2><p class=\"wp-block-paragraph\">One of Laurynas&rsquo; PRs changed several plan and billing pages in the Hostinger dashboard so they&rsquo;d keep working when plan and pricing data loads slowly. Unit tests passed. Continuous integration (CI) checks were green. By the usual standards, it was ready to go.<\/p><p class=\"wp-block-paragraph\">Then the proof subagent opened it on the PR preview, with a fresh test account, and recreated the problem the PR was meant to handle by making plan and pricing data arrive 15 seconds late. The plan downgrade page crashed on every single load.<\/p><p class=\"wp-block-paragraph\">The cause was a chain of dependencies. Opening the page starts a price-estimate request, which first checks whether it can run. That check needs the chosen billing period. The period needs the list of plans you can pick, and that list needs the chosen plan.<\/p><p class=\"wp-block-paragraph\">The PR had changed how the chosen plan was set, but declared it further down the component. So the check reached for the chosen plan before it was initialized.<\/p><p class=\"wp-block-paragraph\">The worker fixed it by declaring each value before anything uses it. It also split the request into two, one for the price estimate and one for the actual order, and added a test that fails if the crash ever comes back.<\/p><p class=\"wp-block-paragraph\">That downgrade test that runs on a real build is what hforge calls proof. It means seeing the change where a user would see it, on a real build, next to the same scenario before the change.<\/p><div class=\"wp-block-image\">\n<figure data-wp-context='{\"imageId\":\"6af34aa3ae401\"}' data-wp-interactive=\"core\/image\" data-wp-key=\"6af34aa3ae401\" class=\"aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" width=\"783\" height=\"2560\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-downgrade-proof-stacked-scaled.png\/public\" alt=\"Four stages of the plan downgrade page: empty plan cards on the live version, a crash on the PR&rsquo;s first commit while CI was green, both plans and the price estimate after the fix, and the Plan downgraded confirmation\" class=\"wp-image-11015\" srcset=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-downgrade-proof-stacked-scaled.png\/w=783,fit=scale-down 783w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-downgrade-proof-stacked-scaled.png\/w=92,fit=scale-down 92w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-downgrade-proof-stacked-scaled.png\/w=313,fit=scale-down 313w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-downgrade-proof-stacked-scaled.png\/w=768,fit=scale-down 768w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-downgrade-proof-stacked-scaled.png\/w=470,fit=scale-down 470w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-downgrade-proof-stacked-scaled.png\/w=626,fit=scale-down 626w\" sizes=\"(max-width: 783px) 100vw, 783px\" \/><button class=\"lightbox-trigger\" type=\"button\" aria-haspopup=\"dialog\" data-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\" data-wp-init=\"callbacks.initTriggerButton\" data-wp-on--click=\"actions.showLightbox\" data-wp-style--right=\"state.thisImage.buttonRight\" data-wp-style--top=\"state.thisImage.buttonTop\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\"><\/path>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div><h3 class=\"wp-block-heading h-t-title-3\">What makes proof trustworthy<\/h3><p class=\"wp-block-paragraph\">Proof only saves reviewers time if they can trust it without double-checking. A few rules make that possible:<\/p><ul class=\"wp-block-list\">\n<li><strong>The agent that wrote the code doesn&rsquo;t check it.<\/strong> A separate proof subagent tests and reports. Its scenarios come from the plan&rsquo;s destination, which the human signed off on before any code was written.<\/li>\n\n\n\n<li><strong>It confirms which build it&rsquo;s testing.<\/strong> If the preview is still serving the old code, say because a deploy hasn&rsquo;t finished or a setting didn&rsquo;t apply, a test can pass without ever touching the change. So before testing, the subagent checks for something only the new build has, like a version string, and notes it with the evidence.<\/li>\n\n\n\n<li><strong>Before and after get a fair fight.<\/strong> Each side gets its own session and test account, because server-side state such as saved progress sticks to an account and can leak from one run into the other. Viewport, data, and A\/B experiments stay identical.<\/li>\n\n\n\n<li><strong>Clicking isn&rsquo;t enough.<\/strong> As hforge&rsquo;s instructions put it, a click that didn&rsquo;t throw proves nothing. So after every step, the agent checks that the expected result happened by reading what&rsquo;s on the page and the requests it sent, for example that the price appears or that the right billing period went to the server.<\/li>\n\n\n\n<li><strong>It looks beyond the change.<\/strong> The agent follows each changed export through its callers until it reaches something a user meets, such as a screen, a route guard, or a redirect. Then it opens those screens on both the old and new builds and compares the errors, so anything the change broke elsewhere shows up as a new one. Tests that mock the changed code don&rsquo;t count, because they skip the path that would fail.<\/li>\n\n\n\n<li><strong>Faked states are labeled.<\/strong> When a screen can only be reached by faking a server response, that evidence goes in a separate <strong>simulated\/<\/strong> folder, so a rerun can&rsquo;t swap it for real evidence.<\/li>\n<\/ul><p class=\"wp-block-paragraph\">Proof also has to be cheap to produce and quick to check, so the evidence stays as light as possible. A screenshot covers most changes. Backend changes have no screen, so their proof is what a caller would see on the real build: the response it gets back and the records the change stored.<\/p><p class=\"wp-block-paragraph\">Things that change over seconds, like a countdown, a loading state, or a notice that disappears on its own, get screenshots at fixed moments. Glitches too brief for a screenshot, like a wrong value that flashes before the right one appears, get a recorder injected into the page that captures what&rsquo;s on screen every few tens of milliseconds. Video is the last resort, for motion and timing.<\/p><h3 class=\"wp-block-heading h-t-title-3\">How proof reaches the reviewer<\/h3><p class=\"wp-block-paragraph\">Once proof comes back, the worker reads the report and steps back. It asks whether a user would expect something else, whether the flow is clumsy, or whether a cleaner design would avoid the approach the code took.<\/p><p class=\"wp-block-paragraph\">If so, it reworks the change before anyone reviews it, while a rework is still cheap.<\/p><p class=\"wp-block-paragraph\">Then a small script, publish-proof, gets the evidence into the PR. It pushes the screenshots to a hidden Git ref that normal clones don&rsquo;t fetch, so they never bloat the repository, and writes the before-and-after pairs into the PR description.<\/p><p class=\"wp-block-paragraph\">It also refuses proof taken on an older commit, so reviewers never see evidence for a version of the change that no longer exists.<\/p><p class=\"wp-block-paragraph\">The PR description itself stays under about 150 words plus images: what changed for the user, the root cause, a test plan, and a short section called &ldquo;Assumptions to check.&rdquo;<\/p><div class=\"wp-block-image\">\n<figure data-wp-context='{\"imageId\":\"6af34aa3b1c8b\"}' data-wp-interactive=\"core\/image\" data-wp-key=\"6af34aa3b1c8b\" class=\"aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" width=\"1468\" height=\"1110\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-assumptions-to-check.png\/public\" alt=\"The Assumptions to check section of a merged hforge PR, listing what the change relies on and what would have to be true for each assumption to be wrong\" class=\"wp-image-11017\" srcset=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-assumptions-to-check.png\/w=1468,fit=scale-down 1468w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-assumptions-to-check.png\/w=300,fit=scale-down 300w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-assumptions-to-check.png\/w=1024,fit=scale-down 1024w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-assumptions-to-check.png\/w=768,fit=scale-down 768w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-assumptions-to-check.png\/w=1467,fit=scale-down 1467w\" sizes=\"(max-width: 1468px) 100vw, 1468px\" \/><button class=\"lightbox-trigger\" type=\"button\" aria-haspopup=\"dialog\" data-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\" data-wp-init=\"callbacks.initTriggerButton\" data-wp-on--click=\"actions.showLightbox\" data-wp-style--right=\"state.thisImage.buttonRight\" data-wp-style--top=\"state.thisImage.buttonTop\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\"><\/path>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div><p class=\"wp-block-paragraph\">The &ldquo;Assumptions to check&rdquo; section moves code review from &ldquo;does this work?&rdquo; to &ldquo;are these decisions right?&rdquo; The proof already answers the first question.<\/p><p class=\"wp-block-paragraph\">One engineer used hforge to open three PRs in repositories he&rsquo;d never touched. Reviewers approved all three without a single comment. He credits the PR descriptions. The proof already showed each change working, so all that was left to review were his assumptions about the user journey.<\/p><h3 class=\"wp-block-heading h-t-title-3\">Where humans still come in<\/h3><p class=\"wp-block-paragraph\">&ldquo;I have definitely stopped reading source code,&rdquo; Laurynas says.<\/p><p class=\"wp-block-paragraph\">With proof attached, he decides how closely to look based on what changed. For a lint change across six pages, he trusts the proof and the AI code reviewer. For changes a user will see, he still looks at the screenshots himself.<\/p><p class=\"wp-block-paragraph\">Proof still misses things, though, and each miss so far has made it better.<\/p><p class=\"wp-block-paragraph\">In one chat widget PR, the proof subagent looked at its screenshots and approved them. Laurynas looked at the same screenshots and saw it was &ldquo;completely broken.&rdquo; The &ldquo;Get AI credits&rdquo; option was floating outside its card, lined up with nothing.<\/p><p class=\"wp-block-paragraph\">Now proof for that kind of change checks layout directly: nothing overlapping, nothing outside its card, and buttons lined up, on wide, narrow, and mobile screens.<\/p><div class=\"wp-block-image\">\n<figure data-wp-context='{\"imageId\":\"6af34aa3b4edc\"}' data-wp-interactive=\"core\/image\" data-wp-key=\"6af34aa3b4edc\" class=\"aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" width=\"1110\" height=\"1156\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-get-ai-credits-1.png\/public\" alt=\"The website builder&rsquo;s start screen twice: in the version that passed proof review, the Get AI credits button floats outside its card, and after the fix it sits inside the card next to a You&rsquo;re out of AI credits message\" class=\"wp-image-11025\" srcset=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-get-ai-credits-1.png\/w=1110,fit=scale-down 1110w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-get-ai-credits-1.png\/w=288,fit=scale-down 288w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-get-ai-credits-1.png\/w=983,fit=scale-down 983w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-get-ai-credits-1.png\/w=768,fit=scale-down 768w\" sizes=\"(max-width: 1110px) 100vw, 1110px\" \/><button class=\"lightbox-trigger\" type=\"button\" aria-haspopup=\"dialog\" data-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\" data-wp-init=\"callbacks.initTriggerButton\" data-wp-on--click=\"actions.showLightbox\" data-wp-style--right=\"state.thisImage.buttonRight\" data-wp-style--top=\"state.thisImage.buttonTop\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\"><\/path>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div><p class=\"wp-block-paragraph\">Another effort touched four repositories. Proof passed on all four PRs, but a human reviewer spotted a release-order problem. If the dashboard shipped before two backend services were live, every user on the new chatbot version would fall back to the old one. Proof tests each PR on its own, so it couldn&rsquo;t see that coming.<\/p><p class=\"wp-block-paragraph\">That effort&rsquo;s proof now includes a run with all four changes together, plus mixed versions, like an old chat widget talking to the new backend. A combined run looks like this one from a teammate&rsquo;s effort, which chained four PRs on staging and tested them with a single end-to-end scenario:<\/p><div class=\"wp-block-image\">\n<figure data-wp-context='{\"imageId\":\"6af34aa3b9f3c\"}' data-wp-interactive=\"core\/image\" data-wp-key=\"6af34aa3b9f3c\" class=\"aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" width=\"800\" height=\"450\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-e2e.gif\/public\" alt=\"An end-to-end test on staging in five steps: an AI Builder site with an email sign-up form is connected to Reach, sign-ups arrive, the site is disconnected in Reach, and a new Reach plan is connected\" class=\"wp-image-11014\"><button class=\"lightbox-trigger\" type=\"button\" aria-haspopup=\"dialog\" data-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\" data-wp-init=\"callbacks.initTriggerButton\" data-wp-on--click=\"actions.showLightbox\" data-wp-style--right=\"state.thisImage.buttonRight\" data-wp-style--top=\"state.thisImage.buttonTop\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\"><\/path>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div><p class=\"wp-block-paragraph\">Even so, he still tests complex flows himself. But he never asks the agent what to test. Its test plan would list the scenarios it already proved, and those almost always work.<\/p><p class=\"wp-block-paragraph\">He&rsquo;d rather come in as an outsider. In his experience, a developer who built a flow knows where its code is messy and fragile, and tends to steer around those parts without noticing. Someone who only knows what the flow should do uses it like a customer and runs straight into them.<\/p><p class=\"wp-block-paragraph\">He compares it to managing a team. No manager reads every line their developers write. They build trust in the process, and when the trust isn&rsquo;t there, they fix the process.<\/p><h2 class=\"wp-block-heading h-t-title-2\" id=\"h-loop-2-a-retro-after-every-task\">Loop 2: a retro after every task<\/h2><p class=\"wp-block-paragraph\">Laurynas says the retro has had the bigger impact of the two. &ldquo;You will find incredible things that your agents just put up with today.&rdquo;<\/p><p class=\"wp-block-paragraph\">Agents behave a lot like a new hire who never mentions the slow laptop. They find a workaround, lose a little time to it every day, and never bring it up. The friction stays until something goes looking for it.<\/p><h3 class=\"wp-block-heading h-t-title-3\">One retro, start to finish<\/h3><p class=\"wp-block-paragraph\">The lint rule that fixed 378 components in a day started with a much smaller PR, one that fixed file uploads in chat onboarding. Once the PR merged, hforge archived the effort and ran a retro over every session involved.<\/p><p class=\"wp-block-paragraph\">At the time, the retro listed every idea it found. It could start the ones it judged safe on its own, and it started two right away.<\/p><p class=\"wp-block-paragraph\">One fixed the PR watch, the process that checks GitHub for the main chat. It had crashed twice after a single failed read. The other stopped parallel proof subagents: when several tried to create test accounts at the same moment, they interfered with each other.<\/p><p class=\"wp-block-paragraph\">Then it gave Laurynas four more ideas to choose from:<\/p><figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Idea<\/strong><\/td><td><strong>What the retro found<\/strong><\/td><td><strong>Proposed fix<\/strong><\/td><\/tr><tr><td>A. Tests before staging proof<\/td><td>One PR took four proof rounds, about two hours. Three rounds found reload bugs a simple test would have caught.<\/td><td>One line in the worker instructions<\/td><\/tr><tr><td>B. Lint rules for the dashboard<\/td><td>About 17 review comments were mechanical, like prop types, import order, and blank lines.<\/td><td>Linter rules, starting as warnings or with an autofix<\/td><\/tr><tr><td>C. Known staging limits<\/td><td>Every proof subagent rediscovered the same staging quirks.<\/td><td>One reference file, plus a one-line pointer to it<\/td><\/tr><tr><td>D. Split the largest dashboard files<\/td><td>Three files had grown to about 1,000 lines each.<\/td><td>Only inside a future effort that touches them<\/td><\/tr><\/tbody><\/table><\/figure><p class=\"wp-block-paragraph\">Laurynas picked B, since a lint rule would catch mechanical comments like those for everyone instead of adding one more instruction for agents to remember. He asked for it as a new effort, with a few rules per PR.<\/p><p class=\"wp-block-paragraph\">Before planning, the agent read 918 review comments across 296 dashboard PRs from the past three months, to check whether those 17 comments were typical. Many weren&rsquo;t.<\/p><p class=\"wp-block-paragraph\">Some of the 17 appeared only one to three times in the whole sample, almost always from a single reviewer on that PR. Named prop and event types came up seven times from two reviewers, so the agent picked rules by how often reviewers repeat them.<\/p><div class=\"wp-block-image\">\n<figure data-wp-context='{\"imageId\":\"6af34aa3be5da\"}' data-wp-interactive=\"core\/image\" data-wp-key=\"6af34aa3be5da\" class=\"aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" width=\"1120\" height=\"630\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-918-review-comments.png\/public\" alt=\"Laurynas asks the agent to turn the lint rule idea into a new effort, and the agent reports checking 918 review comments across 296 dashboard PRs before asking its first scoping question\" class=\"wp-image-11013\" srcset=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-918-review-comments.png\/w=1120,fit=scale-down 1120w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-918-review-comments.png\/w=300,fit=scale-down 300w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-918-review-comments.png\/w=1024,fit=scale-down 1024w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-918-review-comments.png\/w=768,fit=scale-down 768w\" sizes=\"(max-width: 1120px) 100vw, 1120px\" \/><button class=\"lightbox-trigger\" type=\"button\" aria-haspopup=\"dialog\" data-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\" data-wp-init=\"callbacks.initTriggerButton\" data-wp-on--click=\"actions.showLightbox\" data-wp-style--right=\"state.thisImage.buttonRight\" data-wp-style--top=\"state.thisImage.buttonTop\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\"><\/path>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div><p class=\"wp-block-paragraph\">That became a seven-slice effort. The first slice set up the review conventions, and the second added a lint rule requiring named prop and event types in the dashboard&rsquo;s Vue components.<\/p><p class=\"wp-block-paragraph\">Both merged the same day the retro ran. The rule fixed 378 components automatically, without excluding a single file from the rule, and reviewers never had to leave that comment again.<\/p><p class=\"wp-block-paragraph\">Once the two automatic fixes from the start shipped, the retro on that effort started yet another fix on its own: about 170 lines of new code.<\/p><p class=\"wp-block-paragraph\">Laurynas took one look at it and replied, &ldquo;do we really need this PR?&rdquo; The agent backed down right away. Since the PR watch already caught that problem, the extra code wasn&rsquo;t worth keeping.<\/p><p class=\"wp-block-paragraph\">Laurynas closed the PR, and the next retro turned the mistake into a rule: drop any idea that something else already handles. He went one step further and took away the retro&rsquo;s permission to start fixes on its own.<\/p><h3 class=\"wp-block-heading h-t-title-3\">How the retro works<\/h3><p class=\"wp-block-paragraph\">Once every PR in an effort is merged or closed, the main chat archives it, stops any leftover agents and processes, deletes the temporary working copies of each repository, and runs the retro right there in the same chat. That&rsquo;s deliberate, because the retro is a conversation with the human.<\/p><p class=\"wp-block-paragraph\">To find its evidence, the retro searches the session logs on the machine for the effort&rsquo;s folder. That picks up every subagent session without anyone keeping a list.<\/p><p class=\"wp-block-paragraph\">It looks for friction in several areas, such as time spent hunting for the right files, tool calls that cost more than they should, and instructions that don&rsquo;t change anything the agent does. Because it reads the full session logs, it can compare what the agent did with the instructions it had loaded, and spot the ones that made no difference. A repository with no pre-commit hook or CI job running its checks counts as a finding by itself.<\/p><p class=\"wp-block-paragraph\">The area that matters most for running more tasks at once is human toil, meaning anything the human had to do by hand. The retro lists every case, like approving a tool call, picking the agent&rsquo;s own recommendation, or nudging an agent that stalled. Then it suggests what would remove each one: a permission rule, a decision the agent can make alone, or a small script.<\/p><p class=\"wp-block-paragraph\">Since Laurynas took away its permission to act on its own, the retro now presents two fixes for the environment, ranked by how much each would save against what it would cost, and waits for the human to pick. Two is enough to act on at the end of every task without turning the retro into a planning session.<\/p><p class=\"wp-block-paragraph\">When a fix belongs in hforge itself or another skill the whole company uses, the retro doesn&rsquo;t change it directly. It drafts an issue for the skill&rsquo;s maintainers and shows it to the human first, since everyone at the company can see those issues.<\/p><p class=\"wp-block-paragraph\">Once a maintainer folds the fix in, everyone who uses that skill gets it with their next update, so one person&rsquo;s retro improves everyone&rsquo;s agents.<\/p><h3 class=\"wp-block-heading h-t-title-3\">Why the retro picks the cheapest fix<\/h3><p class=\"wp-block-paragraph\">Every line in an agent&rsquo;s always-loaded instructions costs tokens on every run of every task from then on. And the agent can still skip it. So when a retro finds a problem, it also decides where the fix should live. It starts with the cheapest place, measured by how much it adds to what the agent has to read:<\/p><ol class=\"wp-block-list\">\n<li>Delete or rewrite an existing sentence, such as an instruction the agent keeps misreading.<\/li>\n\n\n\n<li>Change a default, like spacing out test account starts so parallel proof subagents stop colliding.<\/li>\n\n\n\n<li>Tell the agent at the moment it needs to know. A script that runs before a commit, or a tool&rsquo;s own error message, can say what to do instead, so the agent only reads it when it&rsquo;s about to go wrong.<\/li>\n\n\n\n<li>Build a command-line tool, like publish-proof, which turned several manual steps into one command.<\/li>\n\n\n\n<li>Add a reference file the agent reads only when it needs it, like a list of known staging limits that every proof subagent would otherwise rediscover.<\/li>\n\n\n\n<li>Add a line to the instructions every run loads, like a rule telling workers to write tests before running staging proof.<\/li>\n<\/ol><p class=\"wp-block-paragraph\">Mechanical violations, like a banned API, imports in the wrong order, or a file in the wrong place, always get a deterministic check: a custom lint rule, a pre-commit hook, or a CI job.<\/p><p class=\"wp-block-paragraph\">Written rules are saved for real judgment calls, and they go to the review agent instead of the implementing agent. The reviewer only has to read the changes, so it has room to check them against the rules. The implementer is already busy exploring the codebase, writing code, and debugging.<\/p><p class=\"wp-block-paragraph\">Even the skills repository behind hforge has a check that flags any change that makes a prompt longer, so even the retro&rsquo;s suggestions have to earn their words.<\/p><h3 class=\"wp-block-heading h-t-title-3\">Faster CI and unit tests<\/h3><p class=\"wp-block-paragraph\">Every hforge task waits on CI. Proof can&rsquo;t start until the PR preview is built, and a PR can&rsquo;t go up for review until its checks pass. The faster those run, the less time each task sits open, and the more of them one person can keep going.<\/p><p class=\"wp-block-paragraph\">Some retros have found ways to make things faster. The biggest came from a retro that looked into the CI runners after agents kept losing time waiting on slow CI, and found they were writing to only one of their six solid-state drives (SSDs).<\/p><p class=\"wp-block-paragraph\">Laurynas forwarded the finding to the infrastructure team and asked whether it was &ldquo;legit or slop.&rdquo; An engineer checked the disks and confirmed it was legit.<\/p><div class=\"wp-block-image\">\n<figure data-wp-context='{\"imageId\":\"6af34aa3c2108\"}' data-wp-interactive=\"core\/image\" data-wp-key=\"6af34aa3c2108\" class=\"aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" width=\"841\" height=\"1011\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/ci-runner-disk-finding-hostname-blurred.png\/public\" alt=\"Laurynas asks an infrastructure engineer whether a retro&rsquo;s finding that CI runners use only one of six SSDs is legit, and the engineer replies with disk output confirming everything is on one disk\" class=\"wp-image-11010\" srcset=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/ci-runner-disk-finding-hostname-blurred.png\/w=841,fit=scale-down 841w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/ci-runner-disk-finding-hostname-blurred.png\/w=250,fit=scale-down 250w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/ci-runner-disk-finding-hostname-blurred.png\/w=768,fit=scale-down 768w\" sizes=\"(max-width: 841px) 100vw, 841px\" \/><button class=\"lightbox-trigger\" type=\"button\" aria-haspopup=\"dialog\" data-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\" data-wp-init=\"callbacks.initTriggerButton\" data-wp-on--click=\"actions.showLightbox\" data-wp-style--right=\"state.thisImage.buttonRight\" data-wp-style--top=\"state.thisImage.buttonTop\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\"><\/path>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div><p class=\"wp-block-paragraph\">After the team spread the work across all six disks, along with some earlier CI changes, the typical wait for a dashboard PR&rsquo;s checks to pass dropped from 9.7 to 4.4 minutes, a55% decrease, queue time included.<\/p><p class=\"wp-block-paragraph\">For the slowest 10% of runs, it dropped from 22.8 to 9.4 minutes, a 59% decrease. The CI machines now spend about 66,000 minutes a month on this work instead of 156,000.<\/p><p class=\"wp-block-paragraph\">Another retro made unit tests twice as fast. The tests run in parallel chunks, called shards, and the test runner was setting up a fresh, isolated environment for every test file. So each shard paid the full setup cost over and over.<\/p><p class=\"wp-block-paragraph\">Switching to one shared environment, with cleanup between tests, cut each shard from 6.1 to 3.0 minutes, and the time spent running the tests within a shard dropped from 246 to 71 seconds.<\/p><div class=\"wp-block-image\">\n<figure data-wp-context='{\"imageId\":\"6af34aa3c56fb\"}' data-wp-interactive=\"core\/image\" data-wp-key=\"6af34aa3c56fb\" class=\"aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" width=\"1128\" height=\"498\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-lint-step-shard-test-1.png\/public\" alt=\"Laurynas&rsquo; Slack update with a timings table showing the unit test shard job dropping from 6.1 to 3.0 minutes and the test step inside a shard from 246 to 71 seconds\" class=\"wp-image-11026\" srcset=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-lint-step-shard-test-1.png\/w=1128,fit=scale-down 1128w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-lint-step-shard-test-1.png\/w=300,fit=scale-down 300w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-lint-step-shard-test-1.png\/w=1024,fit=scale-down 1024w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/4\/2026\/11\/hforge-lint-step-shard-test-1.png\/w=768,fit=scale-down 768w\" sizes=\"(max-width: 1128px) 100vw, 1128px\" \/><button class=\"lightbox-trigger\" type=\"button\" aria-haspopup=\"dialog\" data-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\" data-wp-init=\"callbacks.initTriggerButton\" data-wp-on--click=\"actions.showLightbox\" data-wp-style--right=\"state.thisImage.buttonRight\" data-wp-style--top=\"state.thisImage.buttonTop\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewbox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\"><\/path>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div><h2 class=\"wp-block-heading h-t-title-2\" id=\"h-how-the-two-loops-add-up-to-10-tasks\">How the two loops add up to 10+ tasks<\/h2><p class=\"wp-block-paragraph\">How many tasks Laurynas can run at once comes down to how often each task needs his attention. Proof means he checks evidence instead of reading code, the main chat watches every PR for him, and retros keep removing whatever he still had to do by hand.<\/p><p class=\"wp-block-paragraph\">The two loops also feed each other. The proof subagent reports anything that felt off while testing, even when everything passed, which gives the retro something to work with.<\/p><p class=\"wp-block-paragraph\">When a repository has no setup for capturing proof yet, the subagent builds one and saves it in a folder that every later effort can reuse, so retros keep improving it over time.<\/p><p class=\"wp-block-paragraph\">His own job has shifted along the way. &ldquo;I am moving more into being QA,&rdquo; he says, though a colleague suggested a different title: a <a data-click-id=\"hgr-post-content-link-manager-of-agents\" href=\"https:\/\/www.hostinger.com\/blog\/ai-engineer-at-hostinger\/\">manager of agents<\/a>.<\/p><p class=\"wp-block-paragraph\">Either way, his time now goes to scope, product questions, checking proof, and merging. His attention is the fixed budget. When each task needs roughly a third as much of it, the same day covers about three times as many tasks. That&rsquo;s how four tasks at once became up to 12. In a single month, he merged 678 PRs made with hforge across product and infrastructure repositories.<\/p><h2 class=\"wp-block-heading h-t-title-2\" id=\"h-what-it-takes-to-try-this\">What it takes to try this<\/h2><p class=\"wp-block-paragraph\">Running more tasks at once comes at a price. Proof slows each task down and uses more tokens. One upload PR needed four rounds of proof and about two hours before it passed, and shared staging environments can be slow and flaky, which means more waiting and retries.<\/p><p class=\"wp-block-paragraph\">It works the other way too. The first time proof runs in a repository, the subagent builds a setup for capturing evidence and saves it for later efforts, and every retro after that can improve it. As Laurynas puts it, paired with retro, proofs start coming in faster.<\/p><p class=\"wp-block-paragraph\">Both loops also need the agent to reach a real build, so a team without PR previews or a staging environment would have to set one up first.<\/p><p class=\"wp-block-paragraph\">If that trade-off works for your team, you don&rsquo;t need hforge to start.<\/p><p class=\"wp-block-paragraph\">Laurynas&rsquo; advice is simple: tell your agents to run a retro after each task and look for ways to make their environment easier to work in. One sentence in your agent instructions is enough to get the first retro running and have it propose fixes for you to approve.<\/p><p class=\"wp-block-paragraph\">Proof takes a bit more setup, but the basics work on any stack that has a preview or staging environment. Ask for a before-and-after pair on a real build for every change. Have a separate agent do the checking. Put the evidence on the PR, where reviewers will see it.<\/p><p class=\"wp-block-paragraph\">Once both loops are running, each retro will point you to the next thing slowing your agents down, and every fix frees up a little more of your attention for the next task.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An AI agent finished fixing a file upload bug in the Hostinger dashboard, then suggested something nobody had asked for. Going back through the session, it noticed that a reviewer\u2026<\/p>\n","protected":false},"author":455,"featured_media":11027,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_content_updated_date":"","footnotes":""},"categories":[82],"tags":[],"hashtags":[],"class_list":["post-11000","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engineering"],"hreflangs":[],"_links":{"self":[{"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/posts\/11000","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/users\/455"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/comments?post=11000"}],"version-history":[{"count":1,"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/posts\/11000\/revisions"}],"predecessor-version":[{"id":11028,"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/posts\/11000\/revisions\/11028"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/media\/11027"}],"wp:attachment":[{"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/media?parent=11000"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/categories?post=11000"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/tags?post=11000"},{"taxonomy":"hashtags","embeddable":true,"href":"https:\/\/www.hostinger.com\/blog\/wp-json\/wp\/v2\/hashtags?post=11000"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}