<?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: hefty</title>
    <description>The latest articles on DEV Community by hefty (@hefty_69a4c2d631c9dd70724).</description>
    <link>https://dev.to/hefty_69a4c2d631c9dd70724</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%2F3686846%2Fd23c7b90-6e5c-4c63-a220-85df4d0e14fa.png</url>
      <title>DEV Community: hefty</title>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hefty_69a4c2d631c9dd70724"/>
    <language>en</language>
    <item>
      <title>An AI-Suggested Package Is Not an Install Command</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Sat, 10 Oct 2026 07:08:49 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/an-ai-suggested-package-is-not-an-install-command-35pa</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/an-ai-suggested-package-is-not-an-install-command-35pa</guid>
      <description>&lt;p&gt;A coding agent suggests a package that sounds exactly right for the job. Then it wants to run &lt;code&gt;npm install&lt;/code&gt;. Hold on: a package name in a response is a proposal, not permission to change your dependency tree.&lt;/p&gt;

&lt;p&gt;In a small npm-focused experiment, a DEV.to author gave three AI coding tools 30 everyday tasks and counted six suggestions for nonexistent packages, counted per tool. Two invented names recurred across tools. The author also found two real packages that were very new or little-used. No failed lookup was installed. Those observations are a reason to add a check, not a measured attack rate, a model ranking, or proof that an unfamiliar package is malicious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three different questions get collapsed into one
&lt;/h2&gt;

&lt;p&gt;First: does the &lt;em&gt;exact&lt;/em&gt; package name exist in the registry this project will use? Check the full name, including scope. If the proposed name is missing, don't let the agent quietly pick a lookalike and continue.&lt;/p&gt;

&lt;p&gt;Second: is this the dependency you want? Inspect the intended version, publisher or maintainer information, provenance you can actually verify, and whether the package does the specific job requested. A registry entry answers the existence question. It doesn't answer the trust question. A new package may be perfectly legitimate; its unfamiliarity calls for review, not an automatic accusation.&lt;/p&gt;

&lt;p&gt;Third: what would installation change? The proposed command, manifest edit, lockfile delta, and verification results are separate artifacts. A lockfile shows which dependencies changed; it does not certify that the resulting tree is safe.&lt;/p&gt;

&lt;p&gt;If you only check the first question, you've built a spelling check and called it a security boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put the gate where the action happens
&lt;/h2&gt;

&lt;p&gt;Wove's README describes a useful pattern for file edits: its tooling can enforce read-before-edit and limit large-file rewrites. Those are file-operation controls described by the project, not a claim that Wove audits npm packages or blocks installs.&lt;/p&gt;

&lt;p&gt;Enforce the rule at the tool that performs the action. You can put "verify packages first" in the prompt, but an unrestricted command runner can still install them. File-edit restrictions alone won't stop a package-manager process. The install gate belongs at the process/tool boundary as well.&lt;/p&gt;

&lt;p&gt;Here is a &lt;em&gt;proposed&lt;/em&gt; workflow for a JavaScript task, not a feature test of any agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The agent submits the exact package name, requested version, and why the task needs it. It does not run the install yet.&lt;/li&gt;
&lt;li&gt;The gate checks that name and version against the registry configured for this project. A missing entry stops the request. An unexpected substitute becomes a new proposal, not a silent retry.&lt;/li&gt;
&lt;li&gt;A reviewer checks publisher/version context and task fit. Uncertain provenance pauses for a decision; the gate does not pretend that metadata alone settles trust.&lt;/li&gt;
&lt;li&gt;Only after approval does the command runner receive authority for the reviewed install. Record the actual command and the package/lockfile changes it produced.&lt;/li&gt;
&lt;li&gt;Run the project's relevant checks and attach their results to the dependency change. If a check was skipped, say so.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last step is easy to miss. Approval for one name and version isn't blanket approval for a different version chosen later or for a second package the agent decides to add. Reopen the gate when the proposal changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advice about tools has a provenance problem too
&lt;/h2&gt;

&lt;p&gt;A Hacker News discussion about a proposed shared memory for agent tool reviews immediately raised questions about seeded reviews and vendor gaming. That is community concern, not evidence of a package attack or proof that the proposed review system is compromised. Still, it is a good reminder not to let an agent's recommendation, or a glowing review it found, stand in for the checks above.&lt;/p&gt;

&lt;p&gt;Let the agent propose a dependency. Ask for the exact package, reason, and expected change. Check those details before the runner gets permission to install it. A plausible sentence should never be the thing that authorizes a new dependency.&lt;/p&gt;




&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/harsh2644/i-tested-3-ai-coding-tools-for-slopsquatting-heres-how-many-fake-packages-they-invented-76b"&gt;DEV.to npm package-suggestion experiment&lt;/a&gt; — small-sample name lookups, unfamiliar real packages, and no-install caveat.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mits-pl/wove" rel="noopener noreferrer"&gt;Wove README&lt;/a&gt; — project-described read-before-edit and large-file rewrite controls; not evidence of an npm install gate.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://news.ycombinator.com/item?id=49597472" rel="noopener noreferrer"&gt;Show HN: Pod discussion&lt;/a&gt; — discussion context on provenance and gaming of agent tool reviews, not package-security evidence.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>npm</category>
      <category>security</category>
    </item>
    <item>
      <title>A Coding Agent Is Only as Useful as Its Handoff</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Wed, 07 Oct 2026 13:00:05 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/a-coding-agent-is-only-as-useful-as-its-handoff-2i7k</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/a-coding-agent-is-only-as-useful-as-its-handoff-2i7k</guid>
      <description>&lt;p&gt;A coding agent can finish its turn while the task is still stranded. It changed files, reported success, and left the next developer to reconstruct what it was asked to do, which checks ran, and what still needs a decision.&lt;/p&gt;

&lt;p&gt;The useful unit of agent work is a task someone else can continue or reject. Its handoff needs the acceptance contract, the run boundary, evidence, and a named next action.&lt;/p&gt;

&lt;h2&gt;
  
  
  The agent's chat is a poor task record
&lt;/h2&gt;

&lt;p&gt;Open SWE describes a loop in which a task can enter through an issue, conversation, or schedule, run in a cloud sandbox, produce a PR, and receive follow-up from review or CI. OpenAI's DevDay recap announces reusable cloud environments with shared settings and permissions, along with hosted tool and computer-use capabilities in its Agents API.&lt;/p&gt;

&lt;p&gt;In either workflow, work crosses sessions, tools, and people. A chat transcript may explain a decision. It is a bad place to hide the only copy of the task's current state.&lt;/p&gt;

&lt;p&gt;Community discussion raises two reasonable questions: where does the work live, and what can someone see when a run stalls? Comments and user reports can prompt a better handoff design. They do not establish that any particular product failed to recover.&lt;/p&gt;

&lt;h2&gt;
  
  
  Carry four things to the next person
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. An acceptance contract.&lt;/strong&gt; Record the request and what would count as a finished result. "Improve the release page" is too loose. "Update the hero layout, check the narrow viewport, and prepare the announcement image" gives the reviewer something to inspect. Keep later scope changes visible rather than silently replacing the original request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The run boundary.&lt;/strong&gt; Record the repo and branch, the environment, the tools and permissions granted, and anything outside scope. Reusable environments can save setup, but a reviewer still needs to know which configuration this run used. Open SWE explicitly distinguishes its cloud sandbox workflow from a local CLI that runs commands as the user; the label "agent" does not tell you the boundary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Evidence tied to each acceptance item.&lt;/strong&gt; A diff shows what changed. A passing test will not catch a headline wrapping under a button on a narrow screen. A browser preview will not tell you whether CI passed. Link the artifacts and record failed or skipped checks alongside passing ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. A next owner and action.&lt;/strong&gt; A run can stop at "PR opened," "CI failed," or "needs design review." Name who handles the next step and what they need to decide. Otherwise the agent's final message sounds conclusive while the work sits idle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on a release-page task
&lt;/h2&gt;

&lt;p&gt;Imagine a request to update a release-page hero and prepare an Instagram announcement. This is a hypothetical acceptance exercise, not a run reported by either vendor.&lt;/p&gt;

&lt;p&gt;The page change needs a reviewable diff, a test or build result, and browser previews at the agreed viewport sizes. The announcement needs its own reviewed image export. For that manual publishing step, a reviewer could use &lt;a href="https://resizeimagefor.com/resize-image-for-instagram" rel="noopener noreferrer"&gt;Resize Image for Instagram&lt;/a&gt; to fit, preview, and export the image for a post or Story. The exported file does not prove the page looks right, and the page preview does not prove the image is ready to publish.&lt;/p&gt;

&lt;p&gt;A handoff record for that task could be this small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request: Update release-page hero; prepare Instagram announcement image.
Boundary: &amp;lt;repo/branch, environment, allowed tools and permissions&amp;gt;
Outputs: &amp;lt;PR or diff, browser previews, exported image&amp;gt;
Checks: &amp;lt;command or manual check, result, artifact link for each&amp;gt;
Open issue: &amp;lt;failed/skipped check or decision still needed&amp;gt;
Next action: &amp;lt;owner and the specific review or fix&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fill it with actual links and results as the work happens. If the mobile preview was never opened, write "not checked." If CI failed after the PR, record the failing job and whether the agent is still working on it. A clean record makes uncertainty visible before someone mistakes a confident summary for approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  A PR is a checkpoint, not a verdict
&lt;/h2&gt;

&lt;p&gt;Open SWE's described PR and review loop gives the next person a concrete place to act, but its repository also says the project is under active development. OpenAI's announcement describes cloud capabilities; it does not establish that every long-running task will resume cleanly or that a PR and CI loop is built into every integration. Neither description is a reliability benchmark.&lt;/p&gt;

&lt;p&gt;After the agent stops, another developer should be able to tell what was requested, where the work ran, what was verified, and what to do next without replaying the chat. Code without that record leaves the team to reconstruct the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/langchain-ai/open-swe/" rel="noopener noreferrer"&gt;Open SWE README&lt;/a&gt; — project workflow, cloud sandbox and local CLI boundary, and active-development caveat.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://openai.com/index/devday-2026-recap/" rel="noopener noreferrer"&gt;OpenAI DevDay 2026 recap&lt;/a&gt; — announcement of reusable Codex cloud environments and Agents API capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://news.ycombinator.com/item?id=49896600" rel="noopener noreferrer"&gt;Hacker News DevDay discussion&lt;/a&gt; — discussion context about cloud-agent usefulness and product clarity; not product evidence.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.reddit.com/r/ChatGPTPro/comments/1wu9tie/chatgpt_work_and_codex_after_devday_2026/" rel="noopener noreferrer"&gt;Reddit developer discussion&lt;/a&gt; — anecdotal recovery and visibility concerns; specific failure reports are unverified.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>productivity</category>
      <category>agents</category>
    </item>
    <item>
      <title>A Coding Agent's Permissions Need a Negative Test</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Fri, 02 Oct 2026 05:36:50 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/a-coding-agents-permissions-need-a-negative-test-47lb</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/a-coding-agents-permissions-need-a-negative-test-47lb</guid>
      <description>&lt;p&gt;A runner calls a session "read-only." Fine. Put it in a disposable workspace and ask it to change a file it should not be able to change.&lt;/p&gt;

&lt;p&gt;You need the runner to deny the attempted operation. The agent politely declining proves little.&lt;/p&gt;

&lt;p&gt;This is a test design, not a report of a vulnerability or a test I ran on a particular product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a workspace you can afford to lose
&lt;/h2&gt;

&lt;p&gt;Build a throwaway repo inside an isolated test environment. Give the agent a legitimate job: read a small config file and explain one setting. Then create a separate fixture path outside the allowed worktree but &lt;strong&gt;still inside the disposable environment&lt;/strong&gt;. Put only dummy data there, including a clearly fake token string. Keep real credentials, mounted home directories, production services, and external network access out of the fixture.&lt;/p&gt;

&lt;p&gt;Write down the contract before you prompt the agent. For example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Expected result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read a file in the allowed repo&lt;/td&gt;
&lt;td&gt;Allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change a file in the allowed repo during a read-only run&lt;/td&gt;
&lt;td&gt;Denied&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write to the separate fixture path&lt;/td&gt;
&lt;td&gt;Denied&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read the dummy token from the separate fixture path&lt;/td&gt;
&lt;td&gt;Denied&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reach a test-only listener outside the runner's permitted network scope&lt;/td&gt;
&lt;td&gt;Denied&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apply an agent-proposed patch through the host's patch/apply path&lt;/td&gt;
&lt;td&gt;Denied unless separately authorized&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Only include rows your setup can safely exercise. A network check needs a controlled test listener and an explicit network policy; never use a real secret or a production endpoint as the probe. If the workflow has no patch-apply tool, record that it is unavailable instead of claiming it passed a denial test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the boundary, not the assistant's manners
&lt;/h2&gt;

&lt;p&gt;First run the allowed read. This confirms the fixture works and gives you a baseline. Then attempt one prohibited action at a time with harmless targets. Inspect the tool or executor result &lt;em&gt;and&lt;/em&gt; the fixture afterward. A message saying "permission denied" is useful, but the missing side effect is the other half of the check.&lt;/p&gt;

&lt;p&gt;Record each outcome as one of four things: the tool was not exposed; the runner rejected the attempted call; the agent declined without trying; or the action happened. The third result tells you little about enforcement. A different prompt or an untrusted file in the repo might lead the agent to try the call next time.&lt;/p&gt;

&lt;p&gt;Patch application deserves its own row. An agent may be unable to write directly but still propose a patch for another component to apply. Check the component that actually performs the edit, not just the agent's tool list. Keep this probe within the disposable fixture, and stop if you cannot tell which component owns the final write.&lt;/p&gt;

&lt;p&gt;A denied operation is evidence about this configuration and this route through the tools. It isn't a proof that every possible route is blocked. File access, process execution, and network access can cross different boundaries; changing the runner configuration means running the checks again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop is a separate experiment
&lt;/h2&gt;

&lt;p&gt;Microsoft Foundry Toolkit's release notes describe skill-only toolboxes along with controls to stop active hosted-agent work and reconnect to unfinished responses. Those are useful affordances, but the release entry is not a certification of sandbox isolation or atomic rollback. Discussion about agent trust boundaries on DEV Community and sandbox choices on Reddit raises the same operator question from another direction: what actually happens at the boundary? Neither discussion establishes that a reported security incident occurred or that a particular sandbox is safe.&lt;/p&gt;

&lt;p&gt;For a stop/reconnect check, queue a harmless operation in the fixture, request Stop, and inspect the runner's event or tool record before resuming anything. Separate operations that were never issued, operations already completed, and operations whose outcome you cannot yet confirm. Inspect the filesystem or test listener for effects rather than treating the stopped response as evidence of cancellation.&lt;/p&gt;

&lt;p&gt;If the workflow supports reconnect, compare the resumed run against the same allow/deny contract. An interrupted session shouldn't silently acquire a wider tool surface. That's a requirement you can test in your own runner, not a claim about Foundry's implementation. If an earlier operation may have finished, reconcile that outcome before issuing a retry. A retry may duplicate a side effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put the result in the release gate
&lt;/h2&gt;

&lt;p&gt;A small repo-local assistant that only summarizes files may need a lighter check than a hosted agent with shell tools and network access. Match the fixture to the powers you actually plan to grant. Re-run it when you change the tool list, sandbox policy, patch route, or reconnect behavior.&lt;/p&gt;

&lt;p&gt;If a supposedly denied operation succeeds in the disposable fixture, don't give that configuration access to real resources yet. Fix the executor policy and repeat the test. Changing the label on the button won't fix the boundary.&lt;/p&gt;




&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/microsoft/foundry-dev-tools/blob/main/WHATS_NEW.md" rel="noopener noreferrer"&gt;Microsoft Foundry Toolkit release notes&lt;/a&gt; — primary vendor release entry for skill-only toolboxes and response controls; no isolation or rollback guarantee inferred.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/jeffreyciend/the-ai-agent-trust-boundary-lessons-from-the-codex-sandbox-escapes-4g24"&gt;DEV Community: agent trust-boundary discussion&lt;/a&gt; — secondary discussion and threat-model prompts; its security incident claims are unverified here.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.reddit.com/r/LocalLLaMA/comments/1vrps78/what-sandbox-are-you-all-using-for-ai-agents/" rel="noopener noreferrer"&gt;Reddit: sandbox discussion&lt;/a&gt; — partially accessible practitioner discussion, not proof of a sandbox's safety.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>devtools</category>
      <category>security</category>
      <category>testing</category>
    </item>
    <item>
      <title>Your Coding Agent Needs a Checkpoint Before Its Next Edit</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Wed, 30 Sep 2026 07:39:20 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/your-coding-agent-needs-a-checkpoint-before-its-next-edit-1kd</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/your-coding-agent-needs-a-checkpoint-before-its-next-edit-1kd</guid>
      <description>&lt;p&gt;An agent changes a settings screen, runs a test, and asks to keep going. The transcript is still scrolling. You can see that &lt;em&gt;something&lt;/em&gt; happened, but the next edit may start before anyone has looked at the current one.&lt;/p&gt;

&lt;p&gt;A stop button and a live log help, but neither tells you whether this slice is ready to become the starting point for the next one.&lt;/p&gt;

&lt;p&gt;I'd put a checkpoint there. Show the exact candidate, the checks that ran, what's still unknown, and a decision the runner actually obeys. This is a proposed workflow, not a feature claim about any product discussed below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Freeze the slice, not the whole conversation
&lt;/h2&gt;

&lt;p&gt;Consider a hypothetical request to add a "pause notifications" control. The first slice adds the toggle and saves the preference. The agent then wants to change the notification list UI.&lt;/p&gt;

&lt;p&gt;A useful checkpoint would look roughly like this (illustrative, not a real run log):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Candidate     &amp;lt;revision under review&amp;gt;
Scope         Pause toggle and preference save; list UI untouched
Check        &amp;lt;named test for saving the preference&amp;gt; — pass on this candidate
Browser      &amp;lt;named toggle-and-reload scenario&amp;gt; — not run
Open gap     Keyboard and screen-reader behavior not reviewed
Next slice   Change notification list UI (requires approval)
Decision     Continue | Revise | Stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The card points to a specific change rather than asking you to trust an agent's self-assessment. A test of preference persistence does not establish that the control behaves correctly in a browser. Even a passing browser interaction wouldn't settle keyboard or screen-reader behavior by itself.&lt;/p&gt;

&lt;p&gt;If the agent changes the toggle after that check, the runner must reassess which evidence still applies. Otherwise the UI has turned a passing result for an older candidate into a passing result for whatever code happens to be on screen now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the three buttons mean different things
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Continue&lt;/strong&gt; accepts the reviewed slice and authorizes only the stated next slice. If the runner is free to change unrelated files or launch a deployment, the UI shouldn't call this a bounded approval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revise&lt;/strong&gt; changes the target before more work begins. In the example, the operator might ask for the missing browser scenario, or request a focused fix to the toggle without touching the list. The resulting candidate needs its own review; editing the work does not magically preserve every old check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop&lt;/strong&gt; prevents new work from being scheduled. It should also show what has already been issued to tools and what remains uncertain. Stopping a model response cannot be assumed to cancel an in-flight command, undo a file write, or reverse a deployment. A product that offers Stop needs an executor-side boundary and a way to reconcile effects that crossed it.&lt;/p&gt;

&lt;p&gt;An attractive frontend can lie by accident here. If Continue, Revise, and Stop are labels above one unconstrained agent loop, none of those buttons gives the operator control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this isn't another final approval screen
&lt;/h2&gt;

&lt;p&gt;A product-refactor account on DEV Community describes two principal agents, three review milestones, and checks that included tests and browser workflows. GitHub's account of its Copilot runtime migration describes shipping a much larger Rust change incrementally and treating end-to-end tests as critical. Neither account establishes a universal checkpoint UI or a productivity benchmark. The practical connection is narrower: an increment gives reviewers something they can accept or send back before the next change widens the scope.&lt;/p&gt;

&lt;p&gt;Meanwhile, Foundry Toolkit's release notes describe follow-up and stop controls for active hosted-agent responses, plus inspection updates. That is evidence that runtime steering is getting product attention, not proof that pressing Stop gives atomic cancellation or that Foundry implements the checkpoint proposed here. A Hacker News discussion of coding-agent workflows also shows disagreement about letting agents handle correctness-sensitive tasks. A checkpoint doesn't resolve that disagreement; it makes the acceptance decision explicit.&lt;/p&gt;

&lt;p&gt;For frontend builders, the presentation still matters. If the checkpoint itself is a generated interface, compare component and renderer approaches in &lt;a href="https://awesomegenerativeui.com/resources" rel="noopener noreferrer"&gt;Generative UI resources&lt;/a&gt;. Then keep the actual approval action tied to trusted application state and runner enforcement, not a model-written sentence in a card. The resource is for UI patterns, not evidence that any stop control is safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the gate proportionate
&lt;/h2&gt;

&lt;p&gt;A one-line copy edit probably doesn't need a modal. A change that affects saved preferences, browser behavior, or a user's next action deserves a pause. Pick a point where a reviewer can still reject the current slice without first untangling several more edits.&lt;/p&gt;

&lt;p&gt;Before pressing Continue, I want to know which candidate I'm accepting and which behavior was checked. If the evidence isn't there, Stop must keep the next slice from starting. Otherwise the agent is moving faster than its review loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/maxstravion/what-a-real-product-refactor-revealed-about-ai-coding-agents-2a9o"&gt;DEV Community: product-refactor account&lt;/a&gt; — reported review milestones and mixed checks; one author's case study.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/microsoft/foundry-dev-tools/blob/main/WHATS_NEW.md" rel="noopener noreferrer"&gt;Foundry Toolkit release notes&lt;/a&gt; — response-level follow-up/stop and inspection features; not a cancellation guarantee.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.blog/ai-and-ml/generative-ai/migrating-the-github-copilot-runtime-to-rust-using-copilot/" rel="noopener noreferrer"&gt;GitHub Blog: Copilot runtime migration&lt;/a&gt; — first-party incremental migration and end-to-end test account, not frontend UX evidence.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://news.ycombinator.com/item?id=49726000" rel="noopener noreferrer"&gt;Hacker News: coding-agent workflows and tests&lt;/a&gt; — supporting practitioner disagreement, not a representative survey.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>devtools</category>
    </item>
    <item>
      <title>An Agent Retry Is Not a Rewind Button</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Mon, 28 Sep 2026 09:35:35 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/an-agent-retry-is-not-a-rewind-button-48od</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/an-agent-retry-is-not-a-rewind-button-48od</guid>
      <description>&lt;p&gt;An agent asks a deployment API to create a release. The call times out. The agent restarts with its conversation intact and tries again.&lt;/p&gt;

&lt;p&gt;There may now be two releases. Or one. The timeout tells us what the caller saw, not what the deployment service did. Replaying the conversation cannot settle it.&lt;/p&gt;

&lt;p&gt;This is a hypothetical failure, but the design problem is concrete: once a tool can change something outside the agent process, recovery needs to identify &lt;em&gt;that action&lt;/em&gt; before repeating it. A retry is another request. The external system decides whether it is the same operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three different things called retry
&lt;/h2&gt;

&lt;p&gt;A persisted session lets a replacement process recover conversation and local progress. Kit's project documentation describes append-only session state, crash-safe single-writer locks, and explicit error results for interrupted tool calls. Those are useful controls for resuming work without pretending an incomplete call succeeded.&lt;/p&gt;

&lt;p&gt;Kit also documents reusing an idempotency key for eligible provider-request retries. That key concerns the request to the model provider. It does not make a deployment, payment, or other downstream tool effect happen exactly once.&lt;/p&gt;

&lt;p&gt;The distinction matters during a crash. The session can truthfully record that the agent &lt;em&gt;attempted&lt;/em&gt; a tool call while the remote service has already committed it. The new process has the transcript; it still lacks the remote outcome.&lt;/p&gt;

&lt;p&gt;A builder in a September Hacker News work thread asked how to resume an agent after an irreversible side effect without doing it twice. The question is familiar; the thread doesn't establish a working answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give each consequential action its own identity
&lt;/h2&gt;

&lt;p&gt;Suppose our hypothetical agent is asked to create one release. The harness, rather than the model's next sentence, should assign a stable operation ID to that intended effect. Persist the intended target, payload identity, and ID before dispatch. Record that dispatch is about to happen in durable storage. A later process can then find the attempt even if the original one disappears.&lt;/p&gt;

&lt;p&gt;One possible application-level record looks like this. It is a design sketch, not an API provided by Kit or Latch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operation_id: &amp;lt;stable ID for this intended release&amp;gt;
target: &amp;lt;deployment service and project&amp;gt;
request: &amp;lt;exact release intent / payload reference&amp;gt;
state: planned | sent | confirmed | unknown-reconcile
remote_ref: &amp;lt;release ID, if verified&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;planned&lt;/code&gt; means the intent was recorded. &lt;code&gt;sent&lt;/code&gt; means the process was ready to dispatch; it does &lt;strong&gt;not&lt;/strong&gt; prove the service received the request. &lt;code&gt;confirmed&lt;/code&gt; needs a response or an authoritative lookup tied to the same operation. If the process dies after dispatch but before saving that evidence, recovery treats the outcome as &lt;code&gt;unknown-reconcile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Even this record has a gap: writing &lt;code&gt;sent&lt;/code&gt; locally and committing a release remotely are not one atomic transaction. That's why the operation ID must travel to a remote endpoint that can recognize it, or be usable to look up the outcome afterward. A local log entry alone cannot prevent a duplicate release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resume by inspecting, not guessing
&lt;/h2&gt;

&lt;p&gt;On restart, the replacement process should inspect the operation record and check the deployment service for a matching effect if the service supports such a lookup. If it finds a matching release, save the remote reference and continue without issuing another create request. If it finds an authoritative failure, record that outcome separately.&lt;/p&gt;

&lt;p&gt;If there is no conclusive lookup, a retry is safe only under a suitable upstream deduplication contract: the service must recognize the &lt;em&gt;same&lt;/em&gt; operation ID and payload, for the relevant time window, including concurrent attempts. Reuse the original key; generating a new one defeats the point. A provider-request retry key says nothing about these deployment-service guarantees.&lt;/p&gt;

&lt;p&gt;No lookup and no trustworthy deduplication? Leave the action unresolved and ask an operator to reconcile it. That's frustrating, but it is cheaper than confidently creating a second external effect. Some APIs offer neither a query by client operation ID nor a strong idempotency contract; an agent cannot manufacture either from its transcript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Middleware helps within its actual boundary
&lt;/h2&gt;

&lt;p&gt;Latch's README documents tool-call idempotency, timeouts, circuit breakers, budgets, and compensation patterns. Those are useful building blocks for reducing repeated calls and handling a failed step in a multi-step flow.&lt;/p&gt;

&lt;p&gt;The catch is in the defaults. Latch's idempotency store is in-memory and single-process. Its saga compensation runs in-process; a process death does not automatically resume or compensate the saga. The project is labeled alpha. I'd borrow the patterns, but I wouldn't treat those defaults as crash-durable or promise exactly-once external effects.&lt;/p&gt;

&lt;p&gt;Timeouts need their own handling too. A timeout can mean the request never arrived, or that the effect committed and the acknowledgement was lost. Compensation is different again: undoing a known step after an exception doesn't identify an unknown remote outcome, and some effects cannot be undone at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the boundary where the process vanishes
&lt;/h2&gt;

&lt;p&gt;For a consequential tool, I would review the failure cases before giving an agent an automatic retry policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the process dies just after dispatch, can a different process find the same operation ID and determine whether the effect happened?&lt;/li&gt;
&lt;li&gt;If two workers resume together, what keeps them from issuing competing attempts? A session lock alone doesn't necessarily serialize the remote effect.&lt;/li&gt;
&lt;li&gt;How long does the upstream service retain idempotency keys, and what happens if the same key arrives with different input?&lt;/li&gt;
&lt;li&gt;When a remote result cannot be determined, where does the unresolved action wait for human reconciliation?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If those questions have no answers, keep the session resumable but disable automatic replay for that tool. Investigate the ambiguous write before sending another request.&lt;/p&gt;




&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/speakeasy-api/kit" rel="noopener noreferrer"&gt;Kit coding-agent runtime&lt;/a&gt; — project documentation for session persistence, interrupted calls, and provider-request retries; not evidence of exactly-once external tool effects.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sangaraju1988/latch" rel="noopener noreferrer"&gt;Latch reliability middleware&lt;/a&gt; — project documentation for tool-call controls, with in-memory default storage and in-process saga limitations; alpha, not independently tested here.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://news.ycombinator.com/item?id=49686380" rel="noopener noreferrer"&gt;Ask HN: What are you working on? (September 2026)&lt;/a&gt; — one builder's question about recovering after irreversible side effects; discussion context only.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>devops</category>
      <category>architecture</category>
    </item>
    <item>
      <title>A Coding Agent's UI Should Show Its Limits Before You Press Run</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Thu, 24 Sep 2026 07:20:16 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/a-coding-agents-ui-should-show-its-limits-before-you-press-run-1he5</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/a-coding-agents-ui-should-show-its-limits-before-you-press-run-1he5</guid>
      <description>&lt;p&gt;Imagine asking a coding agent to change a checkout screen. The prompt says what you want. It probably doesn't say whether the agent can read the whole repository, fetch outside information, edit files without approval, or keep spending when the task drags on.&lt;/p&gt;

&lt;p&gt;Those aren't advanced settings for later. They determine what kind of work you have authorized. I would rather see a small preflight before Run than a prettier progress animation afterward.&lt;/p&gt;

&lt;p&gt;This is a UI proposal, not a feature claim about any particular agent. The useful distinction is between telling an agent what to accomplish and deciding the conditions under which it may attempt it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A preference is not a limit
&lt;/h2&gt;

&lt;p&gt;A recent roundup of agent tooling puts managed sessions and cost-aware model routing in the same conversation. It is tempting to turn that into one friendly UI control: "prefer a cheaper model." But that preference doesn't tell an operator how much the run may cost. It also says nothing about which commands the agent may execute.&lt;/p&gt;

&lt;p&gt;If the interface says "economical," I want to know whether it means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a model-selection preference that can choose differently for a given step;&lt;/li&gt;
&lt;li&gt;an enforceable stop condition, if the product has one; or&lt;/li&gt;
&lt;li&gt;just an estimate shown after the work finishes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are different promises. Don't call a routing preference a budget. If a product cannot enforce a monetary cap, say so instead of painting a green "within budget" badge over an estimate. A bounded run might use an explicit limit on tool calls or model usage, but the UI must name the rule it actually enforces.&lt;/p&gt;

&lt;p&gt;Permission is a separate axis. A cheap model with broad file and network access still has broad file and network access. One developer in a coding-agent guardrail discussion argues for a distinct guard rather than relying on opaque model safeguards. That's one builder's position, not a referendum on safety tools, but it points to a useful design boundary: the application should decide which actions require approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put the operating conditions next to Run
&lt;/h2&gt;

&lt;p&gt;Here's a hypothetical preflight for that checkout task. It describes an interface I would build, not an existing product's API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task         Change the checkout screen
Workspace    Current repository; show permitted paths
Context      Repository files only; outside retrieval off
Actions      Read and propose patches; ask before running commands
Routing      Prefer the lower-cost route (preference)
Stop rule    No enforced spend cap configured
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Show the effective defaults, even with a saved preset. "Outside retrieval off" is worth spelling out: a discussion about local coding models and world knowledge illustrates why a user might care whether a run can consult outside context. It doesn't establish that local models perform better or worse. Retrieval is an interface decision independent of the model name.&lt;/p&gt;

&lt;p&gt;If the environment is remote, say where work runs and which workspace is available to it. If the interface offers a path restriction, the executor has to enforce it; a path label that an unrestricted tool can bypass is decoration. The same goes for approvals. A button can request a policy, but the tool boundary must apply it.&lt;/p&gt;

&lt;p&gt;This need not become a giant settings page. A compact card with expandable detail can carry the defaults, with a confirmation step when a run requests more authority. For implementation patterns, &lt;a href="https://awesomegenerativeui.com/resources" rel="noopener noreferrer"&gt;Generative UI resources&lt;/a&gt; collects SDKs, open-source projects, and technical explainers. Borrow presentation ideas if they fit, but don't mistake a UI pattern for enforced permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let the run report the boundary it used
&lt;/h2&gt;

&lt;p&gt;The preflight is a promise about the run, so the interface should reconcile that promise with what actually happened. Show the model route used, which tool actions were allowed or held for approval, whether outside retrieval was used, and the usage or cost information the system can actually observe. Label estimates as estimates.&lt;/p&gt;

&lt;p&gt;If the agent asks to leave the agreed scope, the approval prompt should name the action and why it exceeds the current grant. "Needs permission" tells the operator almost nothing. "Wants to run a command with network access; this run is local-only" gives them a decision to make.&lt;/p&gt;

&lt;p&gt;This is not a substitute for verifying the eventual code change. A bounded run can still produce a bad patch. Preflight answers what the agent was allowed to try; tests and review answer whether the result works. Keeping those questions apart makes both screens more honest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the contract small and real
&lt;/h2&gt;

&lt;p&gt;I wouldn't put every tool switch in front of every user. Most runs can start from a sensible, visible preset, provided the operator can inspect its actual scope and change it before work starts. More detail belongs at the moment a requested action crosses that scope.&lt;/p&gt;

&lt;p&gt;Show the authority, context, and stop rule you can enforce before the agent begins. Label preferences as preferences. If enforcement doesn't exist, a toggle shouldn't imply that it does.&lt;/p&gt;




&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/ai_made_tools/ai-dev-weekly-26-agents-api-full-duplex-voice-swe-2pb9"&gt;AI Dev Weekly #26&lt;/a&gt; — readable Stage 1 roundup; context for routing and application-policy distinctions, not primary vendor documentation.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://news.ycombinator.com/item?id=49803892" rel="noopener noreferrer"&gt;Claude Opus 5.5 discussion&lt;/a&gt; — one builder's guardrail concern; not representative sentiment.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.reddit.com/r/LocalLLaMA/comments/1wn2ybk/ngram_and_world_knowledge_why_are_we_just/" rel="noopener noreferrer"&gt;LocalLLaMA discussion on coding models and knowledge&lt;/a&gt; — supporting discussion of offline context and retrieval tradeoffs, not performance evidence.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Your Coding Agent Needs an `unverified` State</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Fri, 18 Sep 2026 06:39:08 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/your-coding-agent-needs-an-unverified-state-1k3d</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/your-coding-agent-needs-an-unverified-state-1k3d</guid>
      <description>&lt;p&gt;Imagine a coding agent patches a checkout bug. The focused unit test passes. The process exits cleanly. Its final message says the task is done.&lt;/p&gt;

&lt;p&gt;One problem: the request was about a browser checkout flow, and nobody ran that flow.&lt;/p&gt;

&lt;p&gt;The patch may be correct. It may also fail when the payment form, navigation state, and browser runtime meet. The agent has evidence for one claim and no evidence for another. Calling the whole task successful turns a gap in verification into a green badge.&lt;/p&gt;

&lt;p&gt;Coding-agent systems need an explicit &lt;code&gt;unverified&lt;/code&gt; outcome. A run can finish without proving every requested behavior, and the interface should say so.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Done" is carrying too many meanings
&lt;/h2&gt;

&lt;p&gt;Most agent workflows collapse several events into one status:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The process stopped.&lt;/li&gt;
&lt;li&gt;The tool changed something.&lt;/li&gt;
&lt;li&gt;The requested behavior was accepted.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those events are related, but they are not interchangeable.&lt;/p&gt;

&lt;p&gt;A zero exit code tells you that a process completed according to its own exit convention. Reading the file back tells you that bytes were written. A passing unit test tells you that its named assertion held for the candidate and environment it checked. None of those facts automatically proves the whole task.&lt;/p&gt;

&lt;p&gt;The gap gets easier to miss as agents gain more tools. An agent can edit files, launch commands, inspect output, and produce a polished summary. More activity creates more observations. It does not turn those observations into acceptance evidence by itself.&lt;/p&gt;

&lt;p&gt;The workflow needs two axes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;execution_status&lt;/code&gt;: Did the attempt finish, fail, or remain blocked?&lt;/li&gt;
&lt;li&gt;claim-level verification: Which requested behaviors were verified, contradicted, or left unverified?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An attempt can be &lt;code&gt;finished&lt;/code&gt; while one of its claims remains &lt;code&gt;unverified&lt;/code&gt;. That is not a system error. It is an honest description of the available evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track claims, not confidence
&lt;/h2&gt;

&lt;p&gt;A single task badge hides too much. Break the request into claims that can be checked independently.&lt;/p&gt;

&lt;p&gt;For the hypothetical checkout patch, the claims might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the price calculation returns the expected total for a named case&lt;/li&gt;
&lt;li&gt;the payment button becomes enabled after valid input&lt;/li&gt;
&lt;li&gt;the browser completes the requested checkout path&lt;/li&gt;
&lt;li&gt;the patch does not change an unrelated account flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These claims may not all need the same evidence. A focused unit test could cover the calculation. A browser check could cover the interaction. A diff review might show that the patch never touches the account flow, although that still would not guarantee the absence of indirect effects.&lt;/p&gt;

&lt;p&gt;Each claim gets one of three outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;verified&lt;/code&gt;: a named check produced evidence for the claim&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;contradicted&lt;/code&gt;: a named check produced evidence against the claim&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unverified&lt;/code&gt;: the workflow does not have enough relevant evidence either way&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Unverified&lt;/code&gt; is not a softer word for failure. No check was run, the environment was unavailable, or the available check did not cover the claim. &lt;code&gt;Contradicted&lt;/code&gt; means relevant evidence exists and points the other way. Mixing those outcomes makes repair routing worse: one needs a check, while the other needs a code change, a changed requirement, or rejection.&lt;/p&gt;

&lt;p&gt;Claim-level outcomes prevent the opposite mistake too. One failed check should not stain every claim in the task. If the calculation test passes but the browser flow fails, preserve both facts. The system now knows what not to redo and where the repair belongs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a small verification record
&lt;/h2&gt;

&lt;p&gt;The record does not need to become a new observability platform. It needs enough structure to stop prose from laundering uncertainty.&lt;/p&gt;

&lt;p&gt;Here is an illustrative format, not an existing protocol or a claim about any project's API:&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;execution_status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;finished&lt;/span&gt;
&lt;span class="na"&gt;candidate_ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;exact&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;patch&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;revision&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;under&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;review&amp;gt;"&lt;/span&gt;
&lt;span class="na"&gt;claims&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;checkout-total&lt;/span&gt;
    &lt;span class="na"&gt;expected&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;named&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;calculation&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;behavior&amp;gt;"&lt;/span&gt;
    &lt;span class="na"&gt;outcome&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;verified&lt;/span&gt;
    &lt;span class="na"&gt;evidence&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;focused&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;artifact&amp;gt;"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;browser-checkout&lt;/span&gt;
    &lt;span class="na"&gt;expected&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;requested&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;browser&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;behavior&amp;gt;"&lt;/span&gt;
    &lt;span class="na"&gt;outcome&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unverified&lt;/span&gt;
    &lt;span class="na"&gt;evidence&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;browser&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;environment&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;was&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;not&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;available&amp;gt;"&lt;/span&gt;
&lt;span class="na"&gt;next_action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;named&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;browser&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;scenario&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;against&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;this&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;candidate&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The angle brackets matter. They keep the example from looking like a real execution log. In production, those references must point to actual artifacts created by the workflow.&lt;/p&gt;

&lt;p&gt;A useful record answers four practical questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What exact candidate was evaluated?&lt;/li&gt;
&lt;li&gt;What did each check claim to establish?&lt;/li&gt;
&lt;li&gt;Where is the evidence?&lt;/li&gt;
&lt;li&gt;What bounded action would resolve the remaining gap?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should not say &lt;code&gt;all tests passed&lt;/code&gt; when only one test command ran. It should name the check and the requirement it covers. It should not use a file hash as proof of behavior. A hash can identify the candidate; it cannot tell you whether checkout works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence expires when the relevant candidate changes
&lt;/h2&gt;

&lt;p&gt;Verification belongs to a candidate, not to a conversation.&lt;/p&gt;

&lt;p&gt;Suppose the browser flow passes, then the agent edits the checkout component again. The old browser evidence may no longer apply. Keeping the green result attached to the task rather than the checked revision creates a stale proof problem.&lt;/p&gt;

&lt;p&gt;That does not mean every edit invalidates every check. The workflow should connect claims to the files, runtime surfaces, and assumptions they depend on. A documentation correction probably does not invalidate a calculation test. A change to shared form state may invalidate both unit and browser evidence.&lt;/p&gt;

&lt;p&gt;The useful rule is narrower: when the candidate changes, reassess the evidence for affected claims. Preserve unaffected evidence and rerun or downgrade the rest.&lt;/p&gt;

&lt;p&gt;Aiden's published design separates attempts, effects, evidence, verification, and verdicts. The separation lets an effect record survive without being mistaken for a verdict. A parent process can inspect what a worker changed, then decide whether the supplied evidence covers the assigned claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parent agents must verify the handoff
&lt;/h2&gt;

&lt;p&gt;Multi-agent systems make false completion easier.&lt;/p&gt;

&lt;p&gt;A helper returns a confident paragraph: "Implemented the fix and verified the result." The parent sees clean prose, not the boundary of the check. If it accepts the sentence as evidence, the hierarchy only amplifies the helper's confidence.&lt;/p&gt;

&lt;p&gt;The parent should evaluate the handoff against the assignment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is there a candidate artifact to inspect?&lt;/li&gt;
&lt;li&gt;Does the evidence belong to that candidate?&lt;/li&gt;
&lt;li&gt;Does the check address the assigned claim?&lt;/li&gt;
&lt;li&gt;Are unresolved gaps still visible?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a demand for the parent to rerun every command. It is a demand that the parent judge evidence, not tone. A worker's successful exit proves that the worker stopped successfully. Its summary may help a human read the record, but the summary is not the record.&lt;/p&gt;

&lt;p&gt;The same rule applies to human review. Architecture, security, and product behavior often involve judgments that a focused test cannot settle. The system should route those claims to review instead of silently treating machine-checkable evidence as universal approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route the gap instead of hiding it
&lt;/h2&gt;

&lt;p&gt;An &lt;code&gt;unverified&lt;/code&gt; state can look like unfinished work. The work was already unfinished; the state only stops the interface from hiding that fact.&lt;/p&gt;

&lt;p&gt;A good unresolved handoff should include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the last candidate that was checked&lt;/li&gt;
&lt;li&gt;the claims that were verified&lt;/li&gt;
&lt;li&gt;the exact claim that remains open&lt;/li&gt;
&lt;li&gt;the evidence collected so far&lt;/li&gt;
&lt;li&gt;the reason verification stopped&lt;/li&gt;
&lt;li&gt;one safe next action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason matters. Missing browser infrastructure calls for a different response than missing authority to use a payment sandbox. A time budget expiring is different from a check returning a contradiction. If the workflow preserves those distinctions, the next operator can continue without reconstructing the task from a transcript.&lt;/p&gt;

&lt;p&gt;An unresolved handoff also needs a stop condition. If the required environment does not exist, the agent should not invent validation or keep retrying unrelated commands. It should preserve the candidate, name the blocked claim, and stop at the authority or infrastructure boundary.&lt;/p&gt;

&lt;p&gt;Preserving the gap gives the next step a typed input instead of a vague success message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bring the missing check back into view
&lt;/h2&gt;

&lt;p&gt;Return to the checkout patch. The unit test passed, so the calculation claim can be &lt;code&gt;verified&lt;/code&gt; for the checked candidate. The browser flow was never run, so that claim is &lt;code&gt;unverified&lt;/code&gt;. The task is not globally green, and it is not globally failed.&lt;/p&gt;

&lt;p&gt;The next action is small: run the named browser scenario against the same candidate. If it passes, attach the evidence and update that claim. If it fails, mark the claim &lt;code&gt;contradicted&lt;/code&gt; and route the patch back for repair. If the environment remains unavailable, keep the gap visible for a person who can resolve it.&lt;/p&gt;

&lt;p&gt;A coding agent should be allowed to finish its run without pretending it proved the result. An honest &lt;code&gt;unverified&lt;/code&gt; state gives the next developer something better than confidence: it gives them the exact boundary of what is known.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Source notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/taracodlabs/aiden" rel="noopener noreferrer"&gt;Aiden — autonomous AI agent for computer and codebase work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/unfiltered_anshul/open-source-ai-coding-agents-in-2025-which-ones-actually-ship-code-jc8"&gt;Open-Source AI Coding Agents in 2026: Which Ones Actually Ship Code?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>testing</category>
      <category>devtools</category>
    </item>
    <item>
      <title>The Fastest Coding-Agent Step Is the One You Remove From the Loop</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Mon, 14 Sep 2026 10:40:09 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/the-fastest-coding-agent-step-is-the-one-you-remove-from-the-loop-2hk2</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/the-fastest-coding-agent-step-is-the-one-you-remove-from-the-loop-2hk2</guid>
      <description>&lt;p&gt;Put a fast model inside a bad workflow and watch what happens.&lt;/p&gt;

&lt;p&gt;It scans the repository, receives a wall of search output, asks permission for a harmless command, loses the important constraint in the noise, rereads the same files, and finally runs the test that could have run automatically ten minutes earlier. The model may be quick. The task is still slow.&lt;/p&gt;

&lt;p&gt;Coding-agent performance is an end-to-end property. Inference speed matters, but only for the slice of the run spent waiting on inference. The rest is context collection, tool execution, approvals, validation, retries, and recovery.&lt;/p&gt;

&lt;p&gt;Before paying for faster reasoning, remove the turns that never needed reasoning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Count handoffs, not chat messages
&lt;/h2&gt;

&lt;p&gt;A round trip is any handoff that must finish before useful work can continue. It might be another model turn, a tool invocation, a human decision, or a recovery cycle after the run loses state.&lt;/p&gt;

&lt;p&gt;A normal coding-agent loop looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context -&amp;gt; reason -&amp;gt; act -&amp;gt; observe -&amp;gt; approve -&amp;gt; validate -&amp;gt; recover or finish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;None of those phases is automatically waste. The waste appears when boundaries are vague.&lt;/p&gt;

&lt;p&gt;A tool dumps an entire log when the next step needs one error. An approval covers one command instead of a defined risk scope. A failed check returns prose instead of a machine-readable result. A resumed session rebuilds context from the transcript because nobody saved a durable checkpoint.&lt;/p&gt;

&lt;p&gt;Map those handoffs before changing models. Here is an illustrative version, not a proposed standard:&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;context_acquisition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;actor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;retrieval tool&lt;/span&gt;
  &lt;span class="na"&gt;input_boundary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;task contract and allowed repository scope&lt;/span&gt;
  &lt;span class="na"&gt;output_artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;context manifest&lt;/span&gt;
  &lt;span class="na"&gt;repeat_trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;a named evidence gap&lt;/span&gt;

&lt;span class="na"&gt;model_reasoning&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;actor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coding agent&lt;/span&gt;
  &lt;span class="na"&gt;input_boundary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;context manifest and current goal&lt;/span&gt;
  &lt;span class="na"&gt;output_artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;decision or bounded plan&lt;/span&gt;
  &lt;span class="na"&gt;stop_condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;next action and success condition are explicit&lt;/span&gt;

&lt;span class="na"&gt;tool_execution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;actor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deterministic tool&lt;/span&gt;
  &lt;span class="na"&gt;input_boundary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fixed command, files, and limits&lt;/span&gt;
  &lt;span class="na"&gt;output_artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bounded result plus full-log reference&lt;/span&gt;
  &lt;span class="na"&gt;retry_rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;retry only a classified transient failure&lt;/span&gt;

&lt;span class="na"&gt;approval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;actor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;human or policy service&lt;/span&gt;
  &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;named effects and resources&lt;/span&gt;
  &lt;span class="na"&gt;output_artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;decision record&lt;/span&gt;
  &lt;span class="na"&gt;invalidation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scope, target, or reviewed artifact changes&lt;/span&gt;

&lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;actor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test, linter, type checker, or other named check&lt;/span&gt;
  &lt;span class="na"&gt;input_boundary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;candidate artifact&lt;/span&gt;
  &lt;span class="na"&gt;output_artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;structured pass or fail evidence&lt;/span&gt;
  &lt;span class="na"&gt;failure_route&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;repair, escalate, or stop&lt;/span&gt;

&lt;span class="na"&gt;recovery&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;actor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;runtime&lt;/span&gt;
  &lt;span class="na"&gt;input_boundary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;durable checkpoint and classified failure&lt;/span&gt;
  &lt;span class="na"&gt;output_artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restored state and allowed next action&lt;/span&gt;
  &lt;span class="na"&gt;stop_condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;state cannot be restored safely&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The indentation mistake in many real systems is conceptual: everything sits under &lt;code&gt;model_reasoning&lt;/code&gt;. Retrieval, command selection, policy, validation, and recovery all become prompts. The agent keeps talking because the workflow gave it no other way to move.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove the model from deterministic leaf work
&lt;/h2&gt;

&lt;p&gt;Models are useful when the next action depends on incomplete evidence, tradeoffs, or interpretation. They are an expensive control structure for a transform with fixed inputs and a checkable output.&lt;/p&gt;

&lt;p&gt;Formatting is the obvious example. File conversion, schema validation, asset resizing, linting, and many code-generation substeps can also be deterministic. Give them typed inputs, run the tool directly, and return a small result.&lt;/p&gt;

&lt;p&gt;If a generated release image needs platform-ready dimensions, a browser-local utility such as &lt;a href="https://resizeimagefor.com" rel="noopener noreferrer"&gt;Resize Image For&lt;/a&gt; can handle that fixed resize-and-export step without uploading source pixels for processing. Asking an agent to rediscover dimensions, choose an image library, write a temporary script, and inspect the output adds uncertainty to a settled operation.&lt;/p&gt;

&lt;p&gt;The same principle applies inside a repository. If the project already has a formatter command, run it. If a JSON schema decides whether a file is valid, call the validator. If a codemod expresses a known migration, let the agent choose whether the codemod fits, then let the codemod perform the repetitive edits.&lt;/p&gt;

&lt;p&gt;Direct tools do not make the workflow safe by themselves. A deterministic command can still target the wrong files or receive bad input. The benefit is a narrower contract: the agent decides what should happen, while the tool performs a repeatable operation whose output is easier to inspect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bound context without starving the task
&lt;/h2&gt;

&lt;p&gt;"Use less context" is bad advice when applied blindly. Missing a package convention or an acceptance requirement can create more retries than a smaller prompt saves.&lt;/p&gt;

&lt;p&gt;The useful goal is bounded context. Start each run with a stable task contract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the repository state and task goal&lt;/li&gt;
&lt;li&gt;allowed files, commands, and effects&lt;/li&gt;
&lt;li&gt;relevant project instructions&lt;/li&gt;
&lt;li&gt;the expected artifact&lt;/li&gt;
&lt;li&gt;named acceptance checks&lt;/li&gt;
&lt;li&gt;stop and escalation conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Retrieve repository material against that contract. Return the matching symbols, nearby tests, and local instructions instead of dumping a broad search transcript. When a tool produces a large log, keep the full output as an artifact and send the agent the failing check, exit status, and a reference to the detail.&lt;/p&gt;

&lt;p&gt;This also changes recovery. A durable task contract, context manifest, current diff, and latest check result are much cheaper to resume from than a long conversation full of superseded plans.&lt;/p&gt;

&lt;p&gt;Alera's project description makes these surrounding surfaces visible: real PTYs for CLI agents, isolated Git worktrees, lifecycle activity, resource tracking, and persisted sessions. That does not establish a speed advantage. It does show that process state, workspace state, and session state belong in the performance model.&lt;/p&gt;

&lt;p&gt;A fast response cannot compensate for rebuilding all three after every interruption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put approvals at risk boundaries
&lt;/h2&gt;

&lt;p&gt;Approval prompts are often treated as a choice between safety and speed. That framing produces two bad designs: interrupt the operator for every small action, or grant broad authority so the chart looks faster.&lt;/p&gt;

&lt;p&gt;An approval should describe a meaningful boundary. Scope it to the effects that carry risk: changing deployment files, using a credential, writing outside the worktree, opening a network connection, merging a pull request, or publishing an artifact. Let routine operations inside an already approved scope proceed without renegotiation.&lt;/p&gt;

&lt;p&gt;The approval also needs an invalidation rule. Permission to deploy one reviewed artifact should not silently transfer to a different artifact after the agent edits it. A decision tied to a target, scope, and artifact state is useful evidence. A floating "yes" in a transcript is not.&lt;/p&gt;

&lt;p&gt;Proliferate's README presents reusable workflows, isolated task worktrees, parallel agents, and human approval gates as explicit orchestration primitives. Again, that is a project-authored description rather than measured proof. The useful design signal is the separation: workflow steps and approval boundaries exist outside the model's conversational improvisation.&lt;/p&gt;

&lt;p&gt;Some reviews must remain serial. A consequential change may deserve a person reading the final diff even if that adds latency. Optimize the placement and scope of that decision; do not delete it to win a benchmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation should return evidence, not reassurance
&lt;/h2&gt;

&lt;p&gt;An agent saying "the tests should pass" is not a validation phase. Neither is a final message that says the task is complete.&lt;/p&gt;

&lt;p&gt;Where acceptance can be mechanical, let the named checks decide it. The runtime can run tests, lint, type checks, schema checks, build commands, or task-specific assertions without asking the model to narrate each command. Return structured results to the loop:&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;check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pnpm-typecheck&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;failed&lt;/span&gt;
&lt;span class="na"&gt;exit_code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2 errors in src/auth/session.ts&lt;/span&gt;
&lt;span class="na"&gt;artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;logs/pnpm-typecheck-017.txt&lt;/span&gt;
&lt;span class="na"&gt;next_route&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bounded-repair&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model still has a job when a check fails: diagnose the evidence and propose a repair. It should not need to persuade the system that a failed check is close enough.&lt;/p&gt;

&lt;p&gt;This boundary matters after tool upgrades too. A current coding-tool roundup reports changes involving permissions, secret redaction, MCP configuration and trust, and experimental worktree behavior. Those changes sit around inference. An upgraded model can answer faster while the run loses time to a stale integration, a changed entry point, or a permission failure.&lt;/p&gt;

&lt;p&gt;Re-run the workflow checks after an upgrade. Old latency assumptions do not survive a changed execution path merely because the model name stayed familiar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parallel agents change the shape of waiting
&lt;/h2&gt;

&lt;p&gt;Parallelism can reduce elapsed time when tasks are genuinely independent. It can also create more handoffs: worktree setup, task partitioning, shared-state coordination, competing patches, and a larger review queue.&lt;/p&gt;

&lt;p&gt;Count accepted outcomes, not active terminals. Two agents investigating the same failure may produce twice the activity and no additional progress. Four patches waiting on one reviewer are still waiting.&lt;/p&gt;

&lt;p&gt;This is why resource and lifecycle visibility matter. For each worker, preserve the task boundary, current state, produced artifact, and owner of the next decision. Concurrency without those records turns recovery into archaeology.&lt;/p&gt;

&lt;p&gt;Parallel work earns its complexity when overlap removes waiting that cannot be removed another way. It is not a substitute for making one loop legible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark the loop, not the launch demo
&lt;/h2&gt;

&lt;p&gt;The launch discussion for Bullet is useful because its maker attributes speed to several workflow choices: model routing, targeted search, bounded tool output, context hygiene, and fewer round trips. Commenters questioned the comparison methodology. Both sides point to the same requirement: "fast" needs a task envelope.&lt;/p&gt;

&lt;p&gt;Compare representative runs from the same starting state and task class. Record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;latency by phase&lt;/li&gt;
&lt;li&gt;round-trip count by type&lt;/li&gt;
&lt;li&gt;retries and their causes&lt;/li&gt;
&lt;li&gt;the artifact produced&lt;/li&gt;
&lt;li&gt;the named checks that passed or failed&lt;/li&gt;
&lt;li&gt;whether the outcome was accepted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not blend a typo fix with a cross-package migration and call the average meaningful. Do not count a run as fast because it stopped before validation. Do not compare one agent with precise repository instructions against another starting from a vague sentence.&lt;/p&gt;

&lt;p&gt;Fewer round trips are a hypothesis, not a guarantee. One extra retrieval can prevent several repair cycles. One deliberate approval can prevent a costly effect. A model turn that catches a bad assumption may be the quickest part of the run.&lt;/p&gt;

&lt;p&gt;The target is avoidable latency. Preserve the handoffs that carry judgment, authority, or proof.&lt;/p&gt;

&lt;p&gt;That distinction also protects engineering understanding. Removing repetitive work is useful. Removing the points where someone has to understand the architecture, assess a tradeoff, or review a risky diff is how output outruns comprehension.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a round-trip budget before a model leaderboard
&lt;/h2&gt;

&lt;p&gt;For one week, instrument the workflow you already have. You do not need a grand observability platform. A task record with timestamps, handoff types, retries, artifacts, and check results is enough to expose obvious waste.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;repository searches that fetch the same material&lt;/li&gt;
&lt;li&gt;raw tool output repeatedly injected into context&lt;/li&gt;
&lt;li&gt;low-risk actions approved one at a time&lt;/li&gt;
&lt;li&gt;deterministic transforms performed through model turns&lt;/li&gt;
&lt;li&gt;validation delayed until a large patch accumulates&lt;/li&gt;
&lt;li&gt;sessions that cannot resume from a durable artifact&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fix one boundary at a time. Replace repeated discovery with a context manifest. Add a summary contract to a noisy tool. Move a fixed transform behind a direct command. Tie approval to a real risk scope. Run a focused check as soon as the relevant artifact exists.&lt;/p&gt;

&lt;p&gt;Then compare models under the improved workflow. The faster model may still win, and now the comparison measures more than its ability to survive your orchestration overhead.&lt;/p&gt;

&lt;p&gt;Use this order: remove unnecessary turns, bound the remaining handoffs, then compare models.&lt;/p&gt;

&lt;p&gt;Before paying for a faster model, remove the turns that never needed a model.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Source notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/leynier/alera" rel="noopener noreferrer"&gt;Alera&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/proliferate-ai/proliferate" rel="noopener noreferrer"&gt;Proliferate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/aicoding-guide/this-week-in-claude-code-codex-and-gemini-cli-week-of-september-13-2026-1ob5"&gt;This week in Claude Code, Codex and Gemini CLI (week of September 13, 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://news.ycombinator.com/item?id=49283063" rel="noopener noreferrer"&gt;Launch HN: Bullet (YC S26) — A Faster Coding Agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/softwareengineer/comments/1wdb4n/programming_practice_in_todays_dev/" rel="noopener noreferrer"&gt;Programming practice in today's dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>Your Coding Agent UI Needs an Event Model, Not a Chat Transcript</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Sat, 12 Sep 2026 08:25:09 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/your-coding-agent-ui-needs-an-event-model-not-a-chat-transcript-2m82</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/your-coding-agent-ui-needs-an-event-model-not-a-chat-transcript-2m82</guid>
      <description>&lt;p&gt;Imagine a coding agent has been running for 25 minutes. Its transcript is busy. It searched the repository, announced a plan, edited three files, ran a command, apologized for an error, and said it was making one final adjustment.&lt;/p&gt;

&lt;p&gt;The cursor is still moving. What you cannot see is more important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which phase is active?&lt;/li&gt;
&lt;li&gt;Is the agent blocked or still making progress?&lt;/li&gt;
&lt;li&gt;What was the last durable artifact?&lt;/li&gt;
&lt;li&gt;Did the required checks pass?&lt;/li&gt;
&lt;li&gt;What action is safe now?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A chat transcript can contain every sentence the agent produced and still fail to answer all five.&lt;/p&gt;

&lt;p&gt;Chat is useful for instructions and explanations. It is a bad state model. Once an agent runs tools, waits for approval, creates artifacts, and validates work over several minutes, its operator UI needs a structured event stream underneath the conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chat is an explanation layer
&lt;/h2&gt;

&lt;p&gt;Chat became the default agent interface for an obvious reason: models produce text, and people know how to type into a box. That works well when the exchange is short and the output is the product.&lt;/p&gt;

&lt;p&gt;The shape changes when the output is a patch, pull request, deployment plan, or test result. Now the text describes work happening elsewhere. A sentence such as "I'm checking the failing tests" may describe intent, an active process, a retry, or stale narration left behind after a crash.&lt;/p&gt;

&lt;p&gt;The frontend should not have to parse that sentence to decide whether to show a spinner, an approval button, or a recovery action. Prose changes between models and versions. It can arrive late, contradict an earlier message, or sound finished before the acceptance checks run.&lt;/p&gt;

&lt;p&gt;Keep the conversation. Let it carry goals, questions, tradeoffs, and rationale. Put operational truth on a separate channel with stable semantics.&lt;/p&gt;

&lt;p&gt;Current tools are already exposing pieces of this distinction. Microsoft's Foundry Toolkit release notes describe richer model profiling and clearer Agent Inspector handling for events and latency. A recent DEV.to comparison evaluates coding agents through practical concerns such as repository permissions, tests, and knowing when to stop. These are project and author descriptions, not a shared standard, but they point at the same product problem: useful agent interfaces must represent the workflow around generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give the run a small event contract
&lt;/h2&gt;

&lt;p&gt;You do not need to invent a universal agent protocol. Start with the information your interface must render without guessing.&lt;/p&gt;

&lt;p&gt;Here is an illustrative TypeScript model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Phase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;planning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;validation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;EventBase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;runId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;eventId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;phase&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Phase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;correlationId&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AgentEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;EventBase&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;run_queued&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;phase_started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Phase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tool_started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tool_finished&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;succeeded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;durationMs&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;artifact_created&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;artifactRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;approval_required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;requiresAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;approvalId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;approval_resolved&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;approvalId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;approved&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;denied&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;check_finished&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;checkRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;passed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;durationMs&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;run_failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;errorCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;recoverable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;run_completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;checkRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Treat the names as placeholders; the boundaries are what matter.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;runId&lt;/code&gt;, &lt;code&gt;eventId&lt;/code&gt;, and &lt;code&gt;sequence&lt;/code&gt; give the frontend identity and ordering. A correlation ID can join a tool start to its finish or connect a retry to the operation it replaced. The summary stays short enough for a timeline. Large outputs live behind &lt;code&gt;artifactRef&lt;/code&gt; or &lt;code&gt;checkRef&lt;/code&gt; instead of flooding the event payload.&lt;/p&gt;

&lt;p&gt;Durations belong only on operations the runtime can measure. If the system cannot separate model time from network delay, it should not manufacture that distinction for a polished chart.&lt;/p&gt;

&lt;p&gt;An append-only stream is often a good fit because it preserves transitions. The UI can rebuild a projection after reconnecting instead of trusting one giant mutable session object whose history has vanished. That is an implementation option, not a requirement. The contract matters more than whether you call the storage pattern event sourcing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model the states people care about
&lt;/h2&gt;

&lt;p&gt;"Streaming," "running," and "done" are too coarse for an agent that can pause, ask permission, validate a patch, and fail in ways that may or may not be recoverable.&lt;/p&gt;

&lt;p&gt;A practical UI might project events into these states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;queued&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;running&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;waiting_for_approval&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;validating&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;failed_recoverable&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;failed_terminal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;completed&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a proposed state set, not an industry standard. Your workflow may need fewer states or more precise ones. What matters is that each displayed state follows from an event rather than a mood inferred from the latest message.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;waiting_for_approval&lt;/code&gt; deserves special treatment. The run is not progressing, but it has not failed. The interface should preserve what action was requested, the scope of that request, and the decision that resumed or stopped the run. A modal that disappears after one click leaves the timeline unable to explain why the agent gained permission to continue.&lt;/p&gt;

&lt;p&gt;Failure needs similar honesty. A failed test may permit a bounded retry. A revoked credential may require operator action. A corrupted workspace may end the run. Showing the same red "failed" badge for all three forces the user back into logs to discover the available next step.&lt;/p&gt;

&lt;p&gt;Completion should be strict. If the task contract names tests, review, or another acceptance check, &lt;code&gt;run_completed&lt;/code&gt; should reference that evidence. The agent's final "done" message is commentary. It is not an acceptance event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Activity is not progress
&lt;/h2&gt;

&lt;p&gt;A transcript looks productive whenever text keeps arriving. An event timeline can make the same mistake if it rewards volume.&lt;/p&gt;

&lt;p&gt;Ten tool calls might represent ten useful steps. They might also be the same failed search repeated with slightly different wording. Counting events does not tell you which one happened.&lt;/p&gt;

&lt;p&gt;Progress indicators should follow durable milestones: a phase transition, a new diff, an approval decision, or a named check result. If the workflow has no defensible percentage, skip the percentage. "Validation: 2 of 4 checks finished" tells the truth. "87% complete" usually does not.&lt;/p&gt;

&lt;p&gt;The same rule applies to status copy. Prefer "waiting for approval to modify deployment files" over "the agent is thinking." One describes an observable condition and gives the operator a decision. The other decorates uncertainty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Latency needs semantics
&lt;/h2&gt;

&lt;p&gt;One timer cannot explain a long-running agent.&lt;/p&gt;

&lt;p&gt;A run can spend time in a queue, waiting on a model, executing a tool, waiting for a person, or validating an artifact. Those delays call for different responses. Faster model inference will not fix a five-hour approval wait. A quicker shell command will not help a run that keeps choosing the wrong tool.&lt;/p&gt;

&lt;p&gt;Recent launch discussions make this measurement gap visible. Makers describe fewer round trips, bounded tool output, and lower cost, while community replies ask for stronger evidence. Rather than adding another "fast" badge, give operators a latency view that connects measurable phases to outcomes.&lt;/p&gt;

&lt;p&gt;For each correlated operation, record the start and finish when the runtime owns both boundaries. Then show where elapsed time accumulated and whether the operation produced an artifact, a check result, a retry, or a failure. Keep unobserved time labeled as unobserved rather than assigning it to the model by subtraction.&lt;/p&gt;

&lt;p&gt;That makes performance work concrete. It also prevents approval delay and validation time from being misreported as generation latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project one stream into several views
&lt;/h2&gt;

&lt;p&gt;The event stream is infrastructure, not the interface itself. Different users need different projections of the same run.&lt;/p&gt;

&lt;p&gt;A compact status panel can show the current phase, blocker, last durable artifact, acceptance state, and allowed next action. A timeline can preserve transitions for diagnosis. An approval inbox can collect unresolved requests across runs. Artifact and check views can connect a run to its diff, worktree, pull request, logs, and validation results. A latency view can group measured duration by phase and operation.&lt;/p&gt;

&lt;p&gt;This shape matches what is appearing around current multi-agent products. Project discussions connect agent runs with documents and human approval gates. Product descriptions connect them with worktrees, pull requests, artifacts, remote access, and recovery. Those descriptions do not prove reliability or productivity. They do show why a transcript-only UI runs out of room: the work has relationships that paragraphs cannot represent cleanly.&lt;/p&gt;

&lt;p&gt;Keep the event payload bounded. A test log belongs in controlled artifact storage, with the event pointing to it. The same goes for a diff or pull request. References let each view fetch the evidence it needs without turning the timeline into a second database of duplicated blobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recovery starts with an honest last state
&lt;/h2&gt;

&lt;p&gt;An event model alone cannot make recovery safe, but it gives the interface enough information to stop pretending.&lt;/p&gt;

&lt;p&gt;After a disconnect or crash, the UI should be able to show the last accepted sequence, the last durable artifact, whether the failure was marked recoverable, and which action the runtime currently permits. It should also expose uncertainty. A stale connection should look stale, not "running."&lt;/p&gt;

&lt;p&gt;The projection code must expect duplicates, delayed delivery, and reconnects. Event IDs support idempotent handling. Per-run sequence numbers expose gaps and out-of-order delivery. If event 42 arrives before event 41, the UI can wait, refresh, or mark the view incomplete instead of quietly building a fictional timeline.&lt;/p&gt;

&lt;p&gt;This does not replace checkpointing or idempotent tools. It keeps the frontend focused on the information needed to present recovery without guessing at backend state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not turn telemetry into a data leak
&lt;/h2&gt;

&lt;p&gt;Structured events are easier to query and display. They are also easier to retain forever by accident.&lt;/p&gt;

&lt;p&gt;Tool arguments, file paths, prompts, and logs can expose source code or secrets. Capture the smallest summaries and references required to operate the run. Redact deliberately, restrict access, and set retention rules for event and artifact stores. A beautiful inspector is not worth copying sensitive payloads into five projections.&lt;/p&gt;

&lt;p&gt;Small synchronous assistants may not need any of this. If a tool answers in seconds, produces no external artifact, and never waits for permission, a conversation can be enough. The event model earns its complexity when the workflow becomes long-running, tool-using, approval-bearing, or recoverable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The transcript is not the control surface
&lt;/h2&gt;

&lt;p&gt;A transcript tells the story of a run. An event model lets the product operate it.&lt;/p&gt;

&lt;p&gt;With explicit events, the interface can answer the questions that matter: what phase is active, what is blocked, which artifact exists, what passed, and what action is available. Chat can then do what it is good at: helping a person steer the work and understand why the agent made a choice.&lt;/p&gt;

&lt;p&gt;If your frontend has to parse reassuring prose to decide whether the work is complete, it does not have a run model yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/foundry-dev-tools/blob/main/WHATS_NEW.md" rel="noopener noreferrer"&gt;Foundry Toolkit for VS Code: What's New&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sonotommy/8-ai-coding-agents-that-actually-ship-production-code-in-2026-18ch"&gt;8 AI Coding Agents That Actually Ship Production Code in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://news.ycombinator.com/item?id=49390739" rel="noopener noreferrer"&gt;Show HN: Proliferate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://news.ycombinator.com/item?id=49283063" rel="noopener noreferrer"&gt;Launch HN: Bullet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.producthunt.com/products/hob-2" rel="noopener noreferrer"&gt;hob&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Token Price Is a Terrible Metric for Coding-Agent Cost</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Thu, 10 Sep 2026 22:50:10 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/token-price-is-a-terrible-metric-for-coding-agent-cost-j59</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/token-price-is-a-terrible-metric-for-coding-agent-cost-j59</guid>
      <description>&lt;p&gt;Run A uses the cheaper model. It edits the right files, fails a test, retries with a wider change, burns through more tool calls, and stops with a confident completion message. An engineer spends the next hour figuring out which half of the patch can be kept.&lt;/p&gt;

&lt;p&gt;Run B uses a more expensive model. It works from the same repository state, stays inside scope, runs the named checks, and returns a patch the reviewer accepts with one small correction.&lt;/p&gt;

&lt;p&gt;The model line item can make Run A look cheaper. The engineering outcome says otherwise.&lt;/p&gt;

&lt;p&gt;Token price is an input price. It does not tell you what a verified patch cost. If coding agents are doing repository-level work, the useful internal metric is cost per accepted task, with every retry, failed check, recovery step, execution environment, and human intervention left in the ledger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your invoice measures consumption, not completion
&lt;/h2&gt;

&lt;p&gt;Tokens matter. Tool calls matter. Model time and sandbox time matter. You should track all of them.&lt;/p&gt;

&lt;p&gt;They still stop short of the result.&lt;/p&gt;

&lt;p&gt;A provider invoice cannot tell you whether a migration was safe, a visual regression was caught, or the reviewer rejected the patch. It usually cannot associate an abandoned worktree with the accepted patch that replaced it. If the agent switched models halfway through, the bill may split one engineering task across several unrelated line items.&lt;/p&gt;

&lt;p&gt;Current model releases are starting to frame efficiency around the whole agent loop. Meta's Muse Spark 1.3 announcement, for example, claims fewer tokens and tool calls alongside better long-horizon coding behavior. Those are vendor claims, not independently reproduced results here. More importantly, fewer calls are only useful if the run still reaches the acceptance boundary.&lt;/p&gt;

&lt;p&gt;A loop that stops early because it gave up is not efficient. Neither is a loop that says "done" before the test suite disagrees.&lt;/p&gt;

&lt;p&gt;The accounting needs three layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;consumption: model usage, tool calls, execution time, and isolated compute&lt;/li&gt;
&lt;li&gt;failure load: retries, failed checks, abandoned branches, and recovery work&lt;/li&gt;
&lt;li&gt;outcome: accepted, rejected, or incomplete under named checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The third layer keeps the first two honest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the task before measuring the agent
&lt;/h2&gt;

&lt;p&gt;Cost per accepted task becomes nonsense if every run gets a different task.&lt;/p&gt;

&lt;p&gt;A typo fix with a deterministic test is not comparable to a dependency migration across six packages. A generated frontend with visual and interaction requirements is not comparable to renaming a private function. Averaging them into one number creates a tidy dashboard and a bad purchasing decision.&lt;/p&gt;

&lt;p&gt;Define a task envelope before the agent starts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repository revision and working state&lt;/li&gt;
&lt;li&gt;task class and goal&lt;/li&gt;
&lt;li&gt;allowed file and command scope&lt;/li&gt;
&lt;li&gt;authority and time limits&lt;/li&gt;
&lt;li&gt;expected artifact&lt;/li&gt;
&lt;li&gt;acceptance checks&lt;/li&gt;
&lt;li&gt;review decision required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then compare runs inside the same task class. Use the same starting revision when practical. Keep the validation contract stable. If one model gets a precise brief and another gets "fix the app," you are measuring prompt quality as much as model performance.&lt;/p&gt;

&lt;p&gt;The acceptance boundary also has to be explicit. A zero exit code may be one check, but it is not a general definition of success. The boundary could include unit tests, type checks, a migration dry run, browser screenshots, an accessibility scan, or human review of a risky diff. Different tasks need different evidence.&lt;/p&gt;

&lt;p&gt;This metric is local by design. Your repository, harness, and review policy shape the result. Cost per accepted task is useful for comparing choices inside one engineering system, not for declaring a universal winner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put the receipt in the harness
&lt;/h2&gt;

&lt;p&gt;Most teams already have enough raw data to build a useful receipt. The problem is that it lives in separate places: provider usage, terminal logs, worktrees, CI, review comments, and somebody's memory of the failed first attempt.&lt;/p&gt;

&lt;p&gt;The harness is where those records can meet.&lt;/p&gt;

&lt;p&gt;Alera's README describes separate terminals, Git worktrees, lifecycle hooks, quota tracking, and resource attribution in one agentic development environment. Mivia documents isolated worktrees, durable step records, lifecycle hooks, provider choice, and local workflow files. These are project-authored descriptions, not proof that either tool measures every cost correctly. They do show where task-level accounting can attach to real execution.&lt;/p&gt;

&lt;p&gt;A compact receipt could look like this:&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;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;auth-callback-fix-017&lt;/span&gt;
  &lt;span class="na"&gt;repository_revision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;84c19e2&lt;/span&gt;
  &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bounded-bug-fix&lt;/span&gt;
  &lt;span class="na"&gt;goal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fix duplicate callback processing&lt;/span&gt;

&lt;span class="na"&gt;agent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example-provider&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example-model&lt;/span&gt;

&lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/auth/callback.ts&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tests/auth/callback.test.ts&lt;/span&gt;
  &lt;span class="na"&gt;time_minutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;
  &lt;span class="na"&gt;allowed_effects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edit_worktree&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;run_local_tests&lt;/span&gt;
  &lt;span class="na"&gt;forbidden_effects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;

&lt;span class="na"&gt;acceptance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pnpm test --filter auth-callback&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pnpm typecheck&lt;/span&gt;
  &lt;span class="na"&gt;reviewer_decision_required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;consumption&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;input_tokens&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recorded_by_provider&lt;/span&gt;
  &lt;span class="na"&gt;output_tokens&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recorded_by_provider&lt;/span&gt;
  &lt;span class="na"&gt;tool_calls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recorded_by_harness&lt;/span&gt;
  &lt;span class="na"&gt;execution_duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recorded_by_harness&lt;/span&gt;
  &lt;span class="na"&gt;isolated_compute_duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recorded_by_runtime&lt;/span&gt;

&lt;span class="na"&gt;failure_load&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;failed_checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;first auth-callback test run&lt;/span&gt;
  &lt;span class="na"&gt;abandoned_worktrees&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="na"&gt;recovery_steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;reverted out-of-scope config edit&lt;/span&gt;

&lt;span class="na"&gt;human_load&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;approvals&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="na"&gt;intervention&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reviewer requested one scope correction&lt;/span&gt;

&lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;worktrees/auth-callback-fix-017.diff&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;accepted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example does not force every field into dollars. Human review may stay qualitative unless the team records time consistently. The point is traceability: one task, its spend, its failures, its evidence, and its final disposition.&lt;/p&gt;

&lt;p&gt;Store rejected and incomplete receipts too. If the ledger keeps only successful runs, the apparent cost will improve every time the agent fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failed loops are part of the price
&lt;/h2&gt;

&lt;p&gt;Coding-agent cost discussions often drift toward routing: use a cheaper model for easy work, fall back to a stronger model when needed. That can work. It can also hide a pile of waste behind the word "fallback."&lt;/p&gt;

&lt;p&gt;Suppose the first model makes three attempts, expands the diff, and leaves the worktree in an uncertain state. The second model then spends time reconstructing the task and cleaning up before producing the accepted patch. The accepted result belongs to the full chain, not just the final model call.&lt;/p&gt;

&lt;p&gt;The same rule applies to parallel agents. More workers can finish independent tasks faster, but they can also duplicate investigation, collide on shared state, or produce several patches that compete for one review slot. Per-session resource attribution matters because concurrency can raise throughput and waste in the same afternoon.&lt;/p&gt;

&lt;p&gt;This is where durable steps and lifecycle hooks earn their keep. A step boundary gives the harness somewhere to record spend and check outcomes. A validation hook can stop a broken loop before it starts another expensive revision. An abandoned worktree remains associated with the task instead of disappearing from the success story.&lt;/p&gt;

&lt;p&gt;Human intervention belongs in the receipt as well, but do not fake precision. "Reviewer resolved an out-of-scope config edit" is better data than a guessed dollar amount. Over time, repeated interventions reveal where the task contract or harness needs work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Segment by task class before comparing models
&lt;/h2&gt;

&lt;p&gt;A useful evaluation set should look like the work your team wants agents to do.&lt;/p&gt;

&lt;p&gt;For small deterministic edits, acceptance may be cheap: one focused test plus diff review. A migration needs stronger state checks and rollback evidence. Debugging needs a reproduced failure before the patch and a clear signal afterward. Generated frontend work needs browser behavior and visual evidence, not merely code that compiles.&lt;/p&gt;

&lt;p&gt;Keep those classes separate. Within each class, select representative tasks, fix the envelope, and compare accepted outcomes. For a narrow frontend study, a collection of &lt;a href="https://awesomegenerativeui.com/papers" rel="noopener noreferrer"&gt;Generative UI research papers&lt;/a&gt; can help identify domain-specific systems and evaluation ideas worth turning into a task set. The directory is a research surface, not a coding-agent benchmark and not evidence that any model will save money.&lt;/p&gt;

&lt;p&gt;Track the distribution, not only the average. One model may be cheap and predictable on bounded edits while occasionally exploding on migrations. Another may cost more per call but fail less often on long tasks. A single blended number hides the difference that should drive routing.&lt;/p&gt;

&lt;p&gt;Vendor efficiency claims can feed this process as hypotheses. If a release claims fewer tokens or tool calls, run representative local tasks under the same envelope. Check whether accepted-task cost falls, whether the failure rate changes, and whether review gets easier or harder. The local receipt decides whether the claim matters to your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize the harness before the token
&lt;/h2&gt;

&lt;p&gt;The cheapest improvement may have nothing to do with model price.&lt;/p&gt;

&lt;p&gt;Add stop rules so an agent cannot repeat the same failed approach indefinitely. Bound concurrency so every session has an owner and a budget. Persist step records so a fallback does not need to reconstruct the run from chat history. Trigger validation at meaningful boundaries, not only after a large patch has accumulated.&lt;/p&gt;

&lt;p&gt;Execution belongs in the accounting too. Cloudflare's documented Cursor integration separates the agent loop from customer-controlled isolated execution. That architecture does not prove lower cost or better security. It does make the operating boundary visible: commands, repositories, tools, and compute can live outside the model provider, and their cost does not vanish because the token invoice ignores them.&lt;/p&gt;

&lt;p&gt;Once the harness can associate consumption, failures, checks, and acceptance with one task, model pricing becomes useful again. You can see where a cheaper model is genuinely economical, where a stronger model reduces recovery, and where the task contract is causing both to waste time.&lt;/p&gt;

&lt;p&gt;Until then, a low token bill can be an expensive way to produce work nobody should merge.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Source notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://research.meta.ai/blog/introducing-muse-spark-1-3" rel="noopener noreferrer"&gt;Introducing Muse Spark 1.3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/leynier/alera" rel="noopener noreferrer"&gt;Alera&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiviaLabs/mivia-agent" rel="noopener noreferrer"&gt;Mivia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/unfiltered_anshul/open-source-ai-coding-agents-in-2025-which-ones-actually-ship-code-jc8"&gt;Open-Source AI Coding Agents in 2026: Which Ones Actually Ship Code?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/AI_Agents/comments/1w9fh76/how_are_companies_managing_the_cost_of_ai_coding/" rel="noopener noreferrer"&gt;How are companies managing the cost of AI coding agents?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.cloudflare.com/sandbox/tutorials/cursor-cloud-agents/" rel="noopener noreferrer"&gt;Run Cursor Cloud Agents on Cloudflare via self-hosted machines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>A Bigger Context Window Won't Make Your Coding Agent Resumable</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Fri, 04 Sep 2026 12:24:11 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/a-bigger-context-window-wont-make-your-coding-agent-resumable-2cce</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/a-bigger-context-window-wont-make-your-coding-agent-resumable-2cce</guid>
      <description>&lt;p&gt;Your coding agent has been running for eight hours. It edited twelve files, started a dev server, attempted a migration, hit two failing tests, and then lost its session.&lt;/p&gt;

&lt;p&gt;The transcript is still there. It might even fit inside the model's context window. But a fresh process still cannot answer the questions that matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which changes were successfully applied?&lt;/li&gt;
&lt;li&gt;Is the migration safe to run again?&lt;/li&gt;
&lt;li&gt;Is that dev server still alive?&lt;/li&gt;
&lt;li&gt;Which failing test blocked the last step?&lt;/li&gt;
&lt;li&gt;Should the next process resume, roll back, or stop for review?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The transcript survived. The job did not.&lt;/p&gt;

&lt;p&gt;Long-running agent work needs a resume protocol. More context can help a model continue a conversation, but it cannot turn chat history into durable job state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context is not a checkpoint
&lt;/h2&gt;

&lt;p&gt;Conversation context preserves messages, tool calls, and explanations. That is useful. It can remind a model what the user asked and how the session reasoned about the task.&lt;/p&gt;

&lt;p&gt;A checkpoint has a different job. It records what is true about the work now.&lt;/p&gt;

&lt;p&gt;That distinction gets expensive when a run is interrupted. A transcript might say, "I'll update the schema and rerun the tests." It does not necessarily prove that the schema changed, identify which command ran, or preserve its exit code. If the session disappeared between the tool call and the final response, the prose may describe an intention rather than the repository's actual state.&lt;/p&gt;

&lt;p&gt;A replacement process needs a compact operational record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the run's contract&lt;/li&gt;
&lt;li&gt;the last completed step&lt;/li&gt;
&lt;li&gt;changes and external side effects already made&lt;/li&gt;
&lt;li&gt;exact validation results&lt;/li&gt;
&lt;li&gt;the next safe decision&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without that record, recovery starts with archaeology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give the run a bounded contract
&lt;/h2&gt;

&lt;p&gt;"Keep working until it is done" sounds productive, but it is a terrible recovery contract. Done is undefined, authority is open-ended, and a replacement process cannot tell whether the run stopped normally or simply ran out of road.&lt;/p&gt;

&lt;p&gt;A useful contract names the boundary before execution begins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a run ID and owner&lt;/li&gt;
&lt;li&gt;repository and worktree&lt;/li&gt;
&lt;li&gt;the goal and stop condition&lt;/li&gt;
&lt;li&gt;time, tool, and authority limits&lt;/li&gt;
&lt;li&gt;the expected artifact&lt;/li&gt;
&lt;li&gt;the checks that decide whether the artifact is acceptable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nightshift's author describes this shift explicitly: long agent runs become disk-backed, time-bounded jobs with contracts, recovery paths, receipts, and archives. That is a project-authored design, not independent evidence that every run will recover correctly. Still, the operating model is the interesting part. A shift has an end, and its state exists somewhere other than the active chat.&lt;/p&gt;

&lt;p&gt;The stop condition deserves special attention. "Implement authentication" leaves too much room for interpretation. "Prepare a reviewable patch for the login callback, stop before deployment, and record the named test results" gives the next operator something they can inspect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Persist facts at step boundaries
&lt;/h2&gt;

&lt;p&gt;Do not wait until the final response to save state. By then, the process may already be gone.&lt;/p&gt;

&lt;p&gt;Checkpoint after meaningful steps: dependency installation, migration generation, code modification, test execution, browser validation, or any external mutation. The record should stay small. Its purpose is fast re-entry, not a polished diary of everything the agent thought about.&lt;/p&gt;

&lt;p&gt;Mivia's documented workflow offers a useful implementation signal here. Its README describes isolated workflows, per-step run records, lifecycle hooks, and local files. Those features create places where a harness can persist facts before moving forward.&lt;/p&gt;

&lt;p&gt;The word "facts" matters. Save the command and its real result, not "tests look good." Save the files changed, not "updated the frontend." If a check failed, keep the failure visible instead of smoothing it into a progress summary.&lt;/p&gt;

&lt;p&gt;A good checkpoint might say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;last_completed_step: generated migration 0042_add_job_receipts
changed_files:
  - db/migrations/0042_add_job_receipts.sql
  - src/jobs/receipt.ts
checks:
  - command: pnpm test --filter job-receipts
    exit_code: 1
    outcome: 2 tests failed in receipt-retry.test.ts
pending_action: inspect whether retries duplicate an existing receipt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is far more useful than another page of confident narration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track side effects separately
&lt;/h2&gt;

&lt;p&gt;File changes are only part of an agent run. The process may have started services, modified a database, opened a pull request, published an artifact, sent a message, or changed remote configuration.&lt;/p&gt;

&lt;p&gt;Those effects need their own ledger because replaying the original prompt can repeat them.&lt;/p&gt;

&lt;p&gt;A blind retry might apply the same migration twice. It might create a second deployment while the first one is still running. It might overwrite uncertainty with a new sequence of actions that happens to produce cleaner logs.&lt;/p&gt;

&lt;p&gt;A side-effect ledger should answer three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What changed outside the transcript?&lt;/li&gt;
&lt;li&gt;Can the operation be checked safely?&lt;/li&gt;
&lt;li&gt;Is it repeatable, reversible, or neither?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This does not make every action idempotent. It makes the uncertainty visible before another process acts on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recovery must live outside the failed session
&lt;/h2&gt;

&lt;p&gt;A stalled process cannot be the sole owner of its recovery plan. The plan needs to be readable by a fresh process or a human operator with no access to the original model state.&lt;/p&gt;

&lt;p&gt;Recovery should begin with inspection, followed by an explicit decision:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resume&lt;/strong&gt; when the recorded state matches the environment and the pending action is still valid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Roll back&lt;/strong&gt; when a known reversible change should be removed before work continues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalate&lt;/strong&gt; when the evidence is incomplete, the environment drifted, or another action could compound an unknown side effect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why recovery is not the same as retry. Retry repeats an operation. Recovery first establishes what already happened.&lt;/p&gt;

&lt;p&gt;PI-Desktop's project documentation points at the operator-facing side of this problem through project sessions, message-scoped diffs, approvals, and guarded rollback. Those controls do not guarantee safe recovery, and local-first software is not automatically isolated or secure. They do make the unit of change more inspectable than one opaque stream of agent activity.&lt;/p&gt;

&lt;p&gt;A resume protocol can be simple. Here is an operating pattern, not a standard or a security guarantee:&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;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;auth-callback-2026-09-04-01&lt;/span&gt;
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;overnight-agent&lt;/span&gt;
  &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;web-app&lt;/span&gt;
  &lt;span class="na"&gt;worktree&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;../worktrees/auth-callback&lt;/span&gt;

&lt;span class="na"&gt;contract&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;goal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prepare a reviewable login-callback patch&lt;/span&gt;
  &lt;span class="na"&gt;stop_when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;named tests pass or a migration needs approval&lt;/span&gt;
  &lt;span class="na"&gt;time_budget_minutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;90&lt;/span&gt;
  &lt;span class="na"&gt;allowed_effects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edit_worktree&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;run_local_tests&lt;/span&gt;
  &lt;span class="na"&gt;forbidden_effects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;modify_production_data&lt;/span&gt;
  &lt;span class="na"&gt;expected_artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git_diff&lt;/span&gt;

&lt;span class="na"&gt;checkpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;last_completed_step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;add receipt persistence&lt;/span&gt;
  &lt;span class="na"&gt;pending_action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;inspect two retry test failures&lt;/span&gt;
  &lt;span class="na"&gt;changed_files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/jobs/receipt.ts&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db/migrations/0042_add_job_receipts.sql&lt;/span&gt;

&lt;span class="na"&gt;side_effects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;services_started&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;web-dev-server&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3102&lt;/span&gt;
  &lt;span class="na"&gt;external_mutations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;

&lt;span class="na"&gt;evidence&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pnpm test --filter job-receipts&lt;/span&gt;
      &lt;span class="na"&gt;exit_code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="na"&gt;outcome&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2 retry tests failed&lt;/span&gt;

&lt;span class="na"&gt;recovery&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;inspect_first&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git diff --stat&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pnpm test --filter job-receipts&lt;/span&gt;
  &lt;span class="na"&gt;resume_when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;migration is unchanged and failures reproduce&lt;/span&gt;
  &lt;span class="na"&gt;rollback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;discard the isolated worktree&lt;/span&gt;
  &lt;span class="na"&gt;escalate_when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;database state differs from the checkpoint&lt;/span&gt;

&lt;span class="na"&gt;receipt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blocked&lt;/span&gt;
  &lt;span class="na"&gt;reviewer_action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;decide whether receipt creation must be idempotent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The schema is deliberately boring. Boring is good when a process wakes up at 3 a.m. and needs to decide whether a migration already ran.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finish with a receipt, not "done"
&lt;/h2&gt;

&lt;p&gt;A completion message is not evidence. The final receipt should contain the artifacts produced, the exact checks and outcomes, known failures, assumptions, and the next reviewer action.&lt;/p&gt;

&lt;p&gt;This also gives review tools a clean handoff. R3's launch describes a local interface that turns scattered comments into explicit feedback for a coding agent. It is a small, low-engagement project signal rather than adoption evidence, but the shape of the loop is useful: review state becomes an artifact that can follow the job into another session.&lt;/p&gt;

&lt;p&gt;A receipt does not prove correctness. It tells the next reviewer what was checked and what was not. That is enough to replace a vague claim of completion with a reviewable boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let old runs improve new contracts
&lt;/h2&gt;

&lt;p&gt;An archive earns its keep when it changes the next run.&lt;/p&gt;

&lt;p&gt;The ZeroShot launch describes local capture of agent sessions, clustering repeated friction, and drafting reusable workflow improvements. Those are author claims, not measured productivity results. The useful idea is narrower: repeated interruptions can reveal missing fields in the contract.&lt;/p&gt;

&lt;p&gt;If three runs stall because nobody recorded which browser profile owns port 3102, add that ownership to the template. If retries keep duplicating external actions, require idempotency keys or an escalation rule. If reviewers repeatedly ask which checks actually ran, make command outcomes mandatory in the receipt.&lt;/p&gt;

&lt;p&gt;The loop is practical: archive the run, find recurring ambiguity, then remove that ambiguity from the next contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apply the replacement-process test
&lt;/h2&gt;

&lt;p&gt;Before letting an agent run unattended for hours, imagine the current session vanishes halfway through.&lt;/p&gt;

&lt;p&gt;Can a different process inspect durable artifacts and determine the contract, current state, side effects, evidence, and next safe action? Can it choose resume, rollback, or escalation without treating the old transcript as ground truth?&lt;/p&gt;

&lt;p&gt;If the answer is no, a larger context window will only preserve more material to reread. Make the job resumable before making it longer.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Source notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/orwamahmoud/i-stopped-treating-long-ai-coding-runs-like-chats-nightshift-now-treats-them-like-shifts-40ec"&gt;I Stopped Treating Long AI Coding Runs Like Chats — Nightshift Now Treats Them Like Shifts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiviaLabs/mivia-agent" rel="noopener noreferrer"&gt;Mivia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vastsa/PI-Desktop/" rel="noopener noreferrer"&gt;PI-Desktop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://news.ycombinator.com/item?id=49113279" rel="noopener noreferrer"&gt;Show HN: ZeroShot — Agent session monitoring to make your team go faster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://news.ycombinator.com/item?id=48973898" rel="noopener noreferrer"&gt;Show HN: R3 — Review locally and send feedback back to your coding agent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>Four Coding Agents Need Four Workspaces, Not Four Chat Windows</title>
      <dc:creator>hefty</dc:creator>
      <pubDate>Mon, 31 Aug 2026 06:35:44 +0000</pubDate>
      <link>https://dev.to/hefty_69a4c2d631c9dd70724/four-coding-agents-need-four-workspaces-not-four-chat-windows-l63</link>
      <guid>https://dev.to/hefty_69a4c2d631c9dd70724/four-coding-agents-need-four-workspaces-not-four-chat-windows-l63</guid>
      <description>&lt;p&gt;Opening four coding-agent sessions feels like scaling. On a shared machine, it is closer to giving four fast contributors the same repository, shell, credentials, ports, caches, and merge queue without deciding who owns any of them.&lt;/p&gt;

&lt;p&gt;The first failure probably will not come from model quality. One task will restart a dev server while another is testing it. Two workers will touch the same lockfile. A branch will pass its own checks and still conflict with a migration waiting in the merge queue.&lt;/p&gt;

&lt;p&gt;Four chat windows create concurrency. Four owned workspaces plus one deliberate merge queue create a system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parallelism multiplies shared state
&lt;/h2&gt;

&lt;p&gt;Tasks that sound independent in a prompt can overlap in the environment.&lt;/p&gt;

&lt;p&gt;A frontend change and an API change may both edit generated types. Two test runs may expect the same database or browser profile. Separate worktrees can still launch services on the same port, read the same environment variables, and write to shared caches. The agents do not collide in the prompt. They collide in everything the prompt lets them touch.&lt;/p&gt;

&lt;p&gt;This is why adding a second agent changes the job. With one worker, the operator can keep a surprising amount of state in their head. With four, every unstated assumption becomes a race condition or a review problem.&lt;/p&gt;

&lt;p&gt;The fix is to make ownership visible before execution starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  A worktree is the start, not the boundary
&lt;/h2&gt;

&lt;p&gt;Git worktrees are a sensible first step. Each task gets its own branch and working files, so one agent is less likely to overwrite another agent's edits by accident.&lt;/p&gt;

&lt;p&gt;That is useful isolation, but it is narrow isolation.&lt;/p&gt;

&lt;p&gt;A worktree does not reserve a port. It does not separate process trees, temporary directories, credentials, network access, browser state, or external services. Treating it as a sandbox gives the workflow more confidence than the boundary deserves.&lt;/p&gt;

&lt;p&gt;Proliferate is an instructive project example because its documented design pairs isolated task worktrees with visible review state. The important idea is the pairing. Filesystem separation tells you where a patch was produced; task state tells you what should happen to that patch next. The project description is not independent proof that every boundary is solved, and it does not need to be. The pattern is useful on its own.&lt;/p&gt;

&lt;p&gt;For each concurrent task, define at least these ownership boundaries:&lt;/p&gt;

&lt;h3&gt;
  
  
  Workspace ownership
&lt;/h3&gt;

&lt;p&gt;Assign one repository scope, branch, and worktree. State which generated files or shared configuration the task may change. If two tasks own the same file, they are coupled work and should be queued accordingly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Process ownership
&lt;/h3&gt;

&lt;p&gt;Reserve ports, dev servers, test databases, caches, temporary paths, and browser profiles. A process should have a named task owner and a cleanup rule instead of becoming shared background state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Artifact ownership
&lt;/h3&gt;

&lt;p&gt;Name the output before the run begins: a patch, a report, a screenshot set, a migration plan, or some other reviewable object. "Improve the app" is not an artifact contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat authority as a task budget
&lt;/h2&gt;

&lt;p&gt;The easiest setup is to launch every worker from the operator's normal shell. It is also the setup with the least useful separation.&lt;/p&gt;

&lt;p&gt;A task that edits a local component rarely needs every token, deployment command, network destination, and destructive tool available to the human running it. Grant the repository, commands, credentials, and network surface required for that task. Leave the rest out.&lt;/p&gt;

&lt;p&gt;Current agent harnesses do not all enforce these boundaries in the same way. If a tool cannot restrict a credential or network path, write that limitation into the run record and reduce the task's authority. Do not silently treat the operator's full shell as a reasonable default.&lt;/p&gt;

&lt;p&gt;This also makes failures easier to understand. When a task has a small authority budget, the failure surface is smaller: you can see which files, processes, and external systems were in play without reconstructing the whole machine after the fact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep integration serial on purpose
&lt;/h2&gt;

&lt;p&gt;Implementation can run in parallel. Integration should have one owner and an explicit order.&lt;/p&gt;

&lt;p&gt;Two patches can both be locally correct and still disagree about an API shape, migration sequence, dependency version, generated file, or user-visible behavior. Git may merge the text cleanly while the combined system is wrong. That is an integration conflict even when there are no conflict markers.&lt;/p&gt;

&lt;p&gt;Give one person, or one tightly bounded integration role, responsibility for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;choosing the review order&lt;/li&gt;
&lt;li&gt;resolving overlapping decisions&lt;/li&gt;
&lt;li&gt;rerunning checks against the combined state&lt;/li&gt;
&lt;li&gt;deciding what lands and what returns for another pass&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The merge queue is where parallel work becomes one product. Making it serial is coordination, not wasted parallelism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Completion needs evidence, not a status message
&lt;/h2&gt;

&lt;p&gt;An agent saying "done" proves that it generated a completion message. It does not prove the patch works.&lt;/p&gt;

&lt;p&gt;Every task should return an evidence bundle with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the changed files and the intent of the diff&lt;/li&gt;
&lt;li&gt;the exact checks run and their real results&lt;/li&gt;
&lt;li&gt;screenshots or browser evidence when behavior is visual&lt;/li&gt;
&lt;li&gt;known failures, skipped checks, and unresolved assumptions&lt;/li&gt;
&lt;li&gt;merge-order or conflict notes for the integration owner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repository-native agent systems are starting to expose this control layer directly. GitHub Agentic Workflows defines bounded jobs and safe-output handling. Its August 24 update describes safe-output validation, run steering, inspectable model and catalog state, and clearer startup diagnostics. GitHub Copilot's August releases describe task management, queued prompts, plan/autopilot behavior, and rewind. These are product descriptions, not reliability benchmarks, but the direction is useful: long-running work needs intervention, recovery, and inspectable output.&lt;/p&gt;

&lt;p&gt;The evidence rule also applies to non-code artifacts. If a frontend task produces launch or social graphics, a narrow browser-local step such as &lt;a href="https://resizeimagefor.com" rel="noopener noreferrer"&gt;Resize Image For&lt;/a&gt; can handle resizing, fitting, cropping or padding, previews, and export while keeping source-image processing in the browser. That is easier to review than handing the source files to another remote worker with a broad instruction to "prepare the assets."&lt;/p&gt;

&lt;h2&gt;
  
  
  Write the contract before launching the second agent
&lt;/h2&gt;

&lt;p&gt;A small task record is enough. The exact schema matters less than forcing the decisions into the open.&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;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fix-mobile-navigation&lt;/span&gt;
&lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent-2&lt;/span&gt;
&lt;span class="na"&gt;stop_when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mobile navigation passes the named browser checks&lt;/span&gt;

&lt;span class="na"&gt;workspace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;repository_scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/web&lt;/span&gt;
  &lt;span class="na"&gt;worktree&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;../worktrees/fix-mobile-navigation&lt;/span&gt;
  &lt;span class="na"&gt;shared_files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pnpm-lock.yaml&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;3102&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;web-dev-server&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;browser_profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent-2-mobile&lt;/span&gt;

&lt;span class="na"&gt;authority&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;localhost&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;destructive_tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="na"&gt;expected_artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;code-diff&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test-results&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mobile-screenshots&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;known-issues&lt;/span&gt;

&lt;span class="na"&gt;integration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;merge_owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;human-reviewer&lt;/span&gt;
  &lt;span class="na"&gt;review_after&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;shared-design-token-change&lt;/span&gt;
  &lt;span class="na"&gt;rollback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;discard-worktree-and-branch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an operating record, not a universal security configuration. The point is to make shared state, authority, evidence, and merge order reviewable before they become an incident report.&lt;/p&gt;

&lt;p&gt;If the task cannot fill in these fields, it is probably too vague or too coupled to run concurrently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know when serial work wins
&lt;/h2&gt;

&lt;p&gt;Parallelize tasks with separate state and separate validation paths. A documentation change in one package and an isolated test addition in another may fit well. Shared-schema changes, coupled migrations, global dependency upgrades, and work that relies on one fragile validation environment usually deserve a queue.&lt;/p&gt;

&lt;p&gt;There is no prize for keeping every agent busy. If coordination and verification cost more than the execution time you saved, reduce the agent count.&lt;/p&gt;

&lt;p&gt;Before opening another session, provision its workspace, authority, integration path, and evidence contract. If that is too expensive for the task, keep the work serial.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Source notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/eliseomdq/running-several-coding-agents-in-parallel-on-windows-without-wsl-or-tmux-1onh"&gt;Running several coding agents in parallel on Windows, without WSL or tmux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/proliferate-ai/proliferate" rel="noopener noreferrer"&gt;Proliferate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.github.com/gh-aw/" rel="noopener noreferrer"&gt;GitHub Agentic Workflows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.github.com/gh-aw/blog/2026-08-24-weekly-update/" rel="noopener noreferrer"&gt;Weekly Update - August 24, 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.blog/changelog/2026-08-13-github-copilot-weekly-releases-august-10/" rel="noopener noreferrer"&gt;GitHub Copilot weekly releases - August 10&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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