<?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: Sergio Corruchaga</title>
    <description>The latest articles on DEV Community by Sergio Corruchaga (@sergiocorruchaga).</description>
    <link>https://dev.to/sergiocorruchaga</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%2F4119873%2F8a744885-aa20-42e2-a893-4376526c81bf.jpg</url>
      <title>DEV Community: Sergio Corruchaga</title>
      <link>https://dev.to/sergiocorruchaga</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sergiocorruchaga"/>
    <language>en</language>
    <item>
      <title>The AI thinks, the gate decides — how I made LLM code edits deterministic (and cut token usage 42 )</title>
      <dc:creator>Sergio Corruchaga</dc:creator>
      <pubDate>Thu, 10 Sep 2026 21:18:28 +0000</pubDate>
      <link>https://dev.to/sergiocorruchaga/the-ai-thinks-the-gate-decides-how-i-made-llm-code-edits-deterministic-and-cut-token-usage-42x-5cbi</link>
      <guid>https://dev.to/sergiocorruchaga/the-ai-thinks-the-gate-decides-how-i-made-llm-code-edits-deterministic-and-cut-token-usage-42x-5cbi</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkv6kh7ce0ax12udd2ay8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkv6kh7ce0ax12udd2ay8.png" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;title: "The AI thinks, the gate decides — how I made LLM code edits deterministic (and cut token usage 42×)"&lt;br&gt;
published: true&lt;/p&gt;
&lt;h2&gt;
  
  
  tags: ai, opensource, typescript, llm
&lt;/h2&gt;
&lt;h1&gt;
  
  
  The AI thinks, the gate decides
&lt;/h1&gt;
&lt;h2&gt;
  
  
  D-Engine: a deterministic harness that matches coding agents' quality while burning 14–42× fewer tokens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sergi Corruchaga · September 2026 · D-Engine v0.2.2 (MIT, open source)&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  1. The number that started it all
&lt;/h2&gt;

&lt;p&gt;On September 10, 2026, I ran the same programming task three times, with the same model (DeepSeek V4.1-Flash), the same literal prompt, and the same repository:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"En utils.ts, añade una función formatDate que reciba un Date y devuelva DD/MM/YYYY"&lt;/em&gt;&lt;br&gt;
(Add a formatDate function to utils.ts that takes a Date and returns DD/MM/YYYY)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All three runs produced functionally the same code. Here's what each one cost:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Architecture&lt;/th&gt;
&lt;th&gt;Tokens consumed&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;D-Engine&lt;/strong&gt; (my harness)&lt;/td&gt;
&lt;td&gt;Deterministic pipeline&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2,552&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~4 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dsh — Minimal mode&lt;/td&gt;
&lt;td&gt;Agent (single tool: shell)&lt;/td&gt;
&lt;td&gt;34,600&lt;/td&gt;
&lt;td&gt;1m 04s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dsh — effort Off&lt;/td&gt;
&lt;td&gt;Full agent, no thinking&lt;/td&gt;
&lt;td&gt;37,100&lt;/td&gt;
&lt;td&gt;6 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dsh — factory defaults&lt;/td&gt;
&lt;td&gt;Full agent, thinking High&lt;/td&gt;
&lt;td&gt;107,000&lt;/td&gt;
&lt;td&gt;28 s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;DeepSeek's official agent burned &lt;strong&gt;42× more tokens&lt;/strong&gt; than my tool to produce the same diff. And as you'll see in the controls section, that gap is explained neither by the model, nor by "thinking mode", nor by the agent's toolbox. It's explained by the architecture.&lt;/p&gt;

&lt;p&gt;This article covers how I got here: what D-Engine is, how I ran the full benchmark (10 tasks, 5 contenders, 2 deliberate traps), what agents do &lt;em&gt;better&lt;/em&gt; than my tool (quite a few things, and I'm going to disclose all of them), and why I believe the future of AI-assisted programming isn't a smarter agent — it's a stricter gate.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. The problem: how an agent spends tokens
&lt;/h2&gt;

&lt;p&gt;The dominant AI coding tools (OpenCode, Aider, dsh, Claude Code…) all follow the same pattern: the &lt;strong&gt;agentic loop&lt;/strong&gt;. The model receives your request, decides to call a tool (&lt;code&gt;read file&lt;/code&gt;, &lt;code&gt;search&lt;/code&gt;, &lt;code&gt;run shell&lt;/code&gt;), gets the result, decides another call, and so on until done.&lt;/p&gt;

&lt;p&gt;The commonly overlooked detail: &lt;strong&gt;the model has no memory between calls&lt;/strong&gt;. On every turn of the loop, the harness re-sends the full system prompt, all tool definitions, and &lt;em&gt;the entire conversation trajectory so far&lt;/em&gt;. If the agent takes 20 steps, step 20 re-sends the previous 19. Cost grows quadratically with the agent's diligence — not with your task's difficulty.&lt;/p&gt;

&lt;p&gt;Measured in my benchmark: the same task, in the same repo, with the same model, cost dsh between &lt;strong&gt;32K and 214K tokens&lt;/strong&gt; depending on how many loop turns it decided to take. A 6.6× variance the user neither controls nor can predict.&lt;/p&gt;

&lt;p&gt;There's a second, subtler problem: &lt;strong&gt;state drift&lt;/strong&gt;. The agent works from the "snapshot" of the code it has been reading during the session. If that snapshot goes stale — or the model misremembers it — it will edit something that doesn't exist. Or worse: it will &lt;em&gt;believe&lt;/em&gt; it sees things that don't exist. In section 6 I describe how dsh reported a corrupted file that was perfectly healthy, complete with fabricated line-level evidence.&lt;/p&gt;

&lt;p&gt;The third problem is &lt;strong&gt;atomicity&lt;/strong&gt;: most agents write directly to your working tree. If the change breaks compilation, your main branch is already broken. Some will even auto-commit the disaster.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. The idea: separate "thinking" from "touching"
&lt;/h2&gt;

&lt;p&gt;D-Engine is built on a radical separation of responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The cloud (the LLM) only thinks.&lt;/strong&gt; It receives the minimum necessary context and responds with &lt;code&gt;SEARCH/REPLACE&lt;/code&gt; blocks — patches anchored to existing code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The local, deterministic runtime only touches.&lt;/strong&gt; It applies those blocks in a &lt;em&gt;photocopy&lt;/em&gt; of the repo (a shadow git worktree), compiles with &lt;code&gt;tsc --noEmit&lt;/code&gt;, and &lt;strong&gt;only if the gate is green&lt;/strong&gt; merges into the real repo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical task consumes exactly &lt;strong&gt;2 LLM calls&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Selector&lt;/strong&gt; (optional, ~300 tokens): given a map of the repo, the model picks the minimal set of relevant files. The user confirms — the selection never applies without authorization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proposal&lt;/strong&gt; (~2,000 tokens): the model receives only those files and generates the &lt;code&gt;SEARCH/REPLACE&lt;/code&gt; blocks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything else is local code: the &lt;code&gt;LocalEditor&lt;/code&gt; applies each patch through a 4-strategy cascade (exact match → newline normalization → ignore trailing whitespace → fuzzy at 0.85 threshold), the compiler validates, and &lt;code&gt;commitAndMerge&lt;/code&gt; stages &lt;em&gt;only&lt;/em&gt; the files touched by the patch (with a &lt;code&gt;git status --porcelain&lt;/code&gt; guard that aborts the merge if any foreign file appears, logging the offender's diff before destroying the photocopy).&lt;/p&gt;

&lt;p&gt;There's also a &lt;strong&gt;Verify&lt;/strong&gt; mode adding an optional second phase: send &lt;em&gt;only the modified snippet&lt;/em&gt; for a semantic audit (the model answers &lt;code&gt;OK&lt;/code&gt; / &lt;code&gt;OK_WITH_OBSERVATIONS&lt;/code&gt; / &lt;code&gt;FAIL&lt;/code&gt;). Measured cost: 330–984 tokens per task — 15–30% on top of the proposal. Nearly free semantic safety, on the programmer's demand.&lt;/p&gt;

&lt;p&gt;The project's motto sums up the philosophy: &lt;strong&gt;the AI thinks, the gate decides&lt;/strong&gt;. The model can propose whatever it wants; the only source of truth in the system is the compiler.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. The benchmark
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Methodology
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test repo&lt;/strong&gt;: &lt;code&gt;bench-repo&lt;/code&gt;, a TypeScript mini-shop (products, cart, pricing, utilities), frozen at the &lt;code&gt;benchmark-base&lt;/code&gt; tag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;10 representative tasks&lt;/strong&gt;: add a function, multi-file rename, validation guards, mass JSDoc documentation, cart line deduplication, an operation-ordering bug, an extraction refactor, two &lt;strong&gt;deliberate traps&lt;/strong&gt; (an already-implemented task and an "optimization" of something already optimal), and a full feature (a coupon system with expiration).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules&lt;/strong&gt;: same literal prompt for every contender, &lt;strong&gt;one attempt&lt;/strong&gt; per task, &lt;code&gt;git reset --hard benchmark-base&lt;/code&gt; + &lt;code&gt;git clean -fd&lt;/code&gt; before every run, engine frozen during the benchmark.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contenders&lt;/strong&gt;: OpenCode, Aider, dsh (DeepSeek's official harness), and D-Engine in Fast and Verify modes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Era declaration&lt;/strong&gt;: the original round ran on V4-Flash non-thinking; the dsh round ran on 2026-09-10 on V4.1-Flash — &lt;em&gt;the very day DeepSeek retired the previous model&lt;/em&gt;. The benchmark survived a mid-flight model extinction thanks to declaring model+effort+date per row, plus the control runs in section 6.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Methodological honesty disclosures
&lt;/h3&gt;

&lt;p&gt;Before the results, two confessions. First: two tasks (T3 and T5) turned out to be defective in their first round — the repo already contained what they asked for; the voided rows are preserved in the record as evidence, and the base was fixed. Second: the literal prompts typed in the first round were not preserved (the &lt;code&gt;git clean -fd&lt;/code&gt; cycles wiped Aider's histories, and my own record document stored summaries instead of the actual texts). The original specifications were recovered from the design conversation, prompts were &lt;strong&gt;frozen&lt;/strong&gt; in the record on 2026-09-10, and every later execution uses them verbatim. T1 shares an attested literal prompt across all eras — it is the comparability anchor.&lt;/p&gt;

&lt;p&gt;None of this is glamorous. That's exactly why it's in the article.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Results
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Quality: a statistical tie
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Contender&lt;/th&gt;
&lt;th&gt;Points (max 50)&lt;/th&gt;
&lt;th&gt;Incidents&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenCode&lt;/td&gt;
&lt;td&gt;49/50&lt;/td&gt;
&lt;td&gt;4 on trap T9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;D-Engine Fast&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;48/50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4 on T9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dsh (factory)&lt;/td&gt;
&lt;td&gt;48/50&lt;/td&gt;
&lt;td&gt;4 on T7 (unrequested API added), 4 on T9; 1 hallucination&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aider&lt;/td&gt;
&lt;td&gt;47/50&lt;/td&gt;
&lt;td&gt;4 on T7, 4 on T9; &lt;strong&gt;committed a main branch that didn't compile (T2)&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D-Engine Verify&lt;/td&gt;
&lt;td&gt;46/50&lt;/td&gt;
&lt;td&gt;4 on T7, 4 on T9; false rejection on T6 (parsing bug, since fixed)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Nobody crushed anybody on quality. With the same model, the "textbook" solution converges — on three tasks, three different contenders produced &lt;strong&gt;byte-identical&lt;/strong&gt; files. What differentiates the tools isn't the answer: it's the machinery around the model.&lt;/p&gt;
&lt;h3&gt;
  
  
  Tokens: here's the difference
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Contender&lt;/th&gt;
&lt;th&gt;Tokens per task (avg)&lt;/th&gt;
&lt;th&gt;vs D-Engine Fast&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;D-Engine Fast&lt;/td&gt;
&lt;td&gt;~2,100&lt;/td&gt;
&lt;td&gt;1×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aider&lt;/td&gt;
&lt;td&gt;~2,100&lt;/td&gt;
&lt;td&gt;~1×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D-Engine Verify&lt;/td&gt;
&lt;td&gt;~2,600&lt;/td&gt;
&lt;td&gt;~1.2×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenCode&lt;/td&gt;
&lt;td&gt;~9,700&lt;/td&gt;
&lt;td&gt;~4–5×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dsh&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~93,000 (range 32K–214K)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~44×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(Aider deserves a fair note: it's by far the leanest agent, because it only passes the files you tell it to. Its problem wasn't cost — it was the gate. Keep reading.)&lt;/p&gt;

&lt;p&gt;The full dsh round consumed &lt;strong&gt;~931K tokens&lt;/strong&gt; versus D-Engine Fast's ~21K for the same task set and equivalent results.&lt;/p&gt;
&lt;h3&gt;
  
  
  Time
&lt;/h3&gt;

&lt;p&gt;Fast ~2.7s · Verify ~3.7s · Aider ~4.9s · OpenCode ~14.9s · &lt;strong&gt;dsh ~38s&lt;/strong&gt; (wall clock; its own UI reports ~20s — the gap between both measures, 9 to 66 seconds per task, is startup and latency time the agent doesn't account for).&lt;/p&gt;
&lt;h3&gt;
  
  
  The front-page moment (T2)
&lt;/h3&gt;

&lt;p&gt;Task T2 asked to rename a constant across two files. Aider &lt;strong&gt;warned&lt;/strong&gt; it was missing context ("I don't have them in the chat. Let me know if you want me to review them")… and then &lt;strong&gt;auto-committed a main branch that didn't compile anyway&lt;/strong&gt; (TS2305). Without a compile gate, AI can break your repo &lt;em&gt;while knowing it's breaking it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;D-Engine, on the same task, rejected its own first attempt: the patch compiled in the photocopy but broke &lt;code&gt;index.ts&lt;/code&gt; — the gate caught it, the merge never happened, and main stayed intact. Failing safe isn't a bug: it's the architecture.&lt;/p&gt;
&lt;h3&gt;
  
  
  Trap T9: the most revealing behavior
&lt;/h3&gt;

&lt;p&gt;T9 asked to "optimize &lt;code&gt;calculateTotal&lt;/code&gt; using &lt;code&gt;Array.reduce&lt;/code&gt;"… when the function &lt;strong&gt;already used reduce&lt;/strong&gt;. The perfect answer was "nothing to do here".&lt;/p&gt;

&lt;p&gt;Nobody gave the perfect answer. Every first-round contender made cosmetic changes (4/5). But dsh did something more interesting and more unsettling at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It admitted the trap&lt;/strong&gt; ("it already used reduce") — only OpenCode had done that.&lt;/li&gt;
&lt;li&gt;It found a &lt;strong&gt;real bug&lt;/strong&gt; nobody had asked it to look for: &lt;code&gt;round2(1.005)&lt;/code&gt; returned &lt;code&gt;1.00&lt;/code&gt; instead of &lt;code&gt;1.01&lt;/code&gt; due to binary floating-point noise. A legitimate, valuable find.&lt;/li&gt;
&lt;li&gt;…and then it &lt;strong&gt;fixed it unilaterally&lt;/strong&gt;, modifying &lt;code&gt;utils.ts&lt;/code&gt; (outside the target) and changing the rounding behavior of the &lt;em&gt;entire system&lt;/em&gt;, when the prompt said to "&lt;em&gt;keep&lt;/em&gt; rounding correct".&lt;/li&gt;
&lt;li&gt;And it finished by reporting that &lt;code&gt;src/products.ts&lt;/code&gt; was corrupted ("line 16 reads &lt;code&gt;ndProduct&lt;/code&gt;… it breaks the whole project's compilation"). Manual verification: &lt;strong&gt;the file was intact&lt;/strong&gt;. A hallucination with fabricated line-level evidence, in the same message where it claimed &lt;code&gt;tsc&lt;/code&gt; passed cleanly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The behavior was &lt;em&gt;safe&lt;/em&gt; (it asked permission before touching the "corrupted" file). But had I answered "yes, fix it", the agent would have edited a healthy file chasing a ghost. D-Engine structurally cannot have this class of hallucination: it doesn't opine on repo state — truth comes from &lt;code&gt;tsc&lt;/code&gt;, not from the model.&lt;/p&gt;

&lt;p&gt;The cost of all that unleashed diligence: &lt;strong&gt;214K tokens&lt;/strong&gt; on a task whose correct answer was "nothing to do". One hundred times D-Engine.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. The controls: killing objections before they're raised
&lt;/h2&gt;

&lt;p&gt;I anticipate three objections to the token gap. All three have measured answers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"It's the model"&lt;/strong&gt; → No. The dsh round ran on V4.1-Flash; I ran D-Engine v0.2.2 on &lt;em&gt;the same new model&lt;/em&gt; (adapted the very day of the API migration): 2,552 tokens. Gap intact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"It's thinking mode"&lt;/strong&gt; → Partially. With effort set to &lt;em&gt;Off&lt;/em&gt; (an exact replica of the first round's non-thinking configuration), dsh dropped from 107K to 37.1K. Thinking amplifies the gap ~2.9× (and quadruples loop turns: 12 vs 3 tool calls — a model that "thinks" also &lt;em&gt;wanders&lt;/em&gt; more). But the remaining 14.5× is still there with reasoning off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"It's the tool arsenal"&lt;/strong&gt; → No. In &lt;em&gt;Minimal&lt;/em&gt; mode (a single tool: a persistent shell), dsh consumed 34.6K — practically identical to the full agent without thinking (37.1K). With a primitive shell the agent needed &lt;em&gt;more&lt;/em&gt; turns (11), not fewer: search with &lt;code&gt;Get-ChildItem&lt;/code&gt;, read with &lt;code&gt;Get-Content&lt;/code&gt;, edit with &lt;code&gt;Add-Content&lt;/code&gt; and hand-typed &lt;code&gt;\r\n&lt;/code&gt; escapes, re-read to verify, compile… The cost isn't in the tool schemas. &lt;strong&gt;It's in the loop: every turn re-sends the full trajectory.&lt;/strong&gt; Shrinking the arsenal doesn't shrink tokens; shrinking the loop does.&lt;/p&gt;

&lt;p&gt;Final gap decomposition on T1 (same model, same prompt, same diff):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;D-Engine (pipeline)       2,552 tok   1×     ← no loop
dsh Minimal              34,600 tok   13.6×  ← the arsenal doesn't matter
dsh Off                  37,100 tok   14.5×  ← pure architectural overhead
dsh Factory (thinking)  107,000 tok   42×    ← thinking amplifies ~2.9×
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. What agents do better (and it would be dishonest to hide it)
&lt;/h2&gt;

&lt;p&gt;This article is not "agents are bad". dsh produced, by far, the most diligent work in the benchmark:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It self-verified&lt;/strong&gt;: compiling with &lt;code&gt;tsc&lt;/code&gt; inside its own loop, and on two tasks it went as far as &lt;em&gt;executing the program&lt;/em&gt; to confirm the output was identical before and after the change. No other contender did that.&lt;/li&gt;
&lt;li&gt;On T10 it wrote a &lt;strong&gt;23-case edge-case suite&lt;/strong&gt; for the coupon system (same-day expiration, &lt;code&gt;NaN&lt;/code&gt; dates, JavaScript's February 31st…), ran it — 23/23 — and deleted it afterwards. Brilliant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It can create new files&lt;/strong&gt;; D-Engine can't yet (documented limitation, on the roadmap).&lt;/li&gt;
&lt;li&gt;It detected dead code, duplications, and a validation hole in &lt;code&gt;applyDiscount&lt;/code&gt;, and &lt;strong&gt;reported them without touching anything&lt;/strong&gt;, asking permission. Exemplary scope discipline — when it chooses to have it.&lt;/li&gt;
&lt;li&gt;It found a real rounding bug I didn't know existed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest conclusion isn't that agents are unnecessary. It's that today you pay for their diligence blind: you don't know if your task will cost 32K or 214K tokens, whether the agent will respect your scope or redecorate half your repo, or whether its report about your code's state is true or a plausible hallucination. D-Engine proposes the inverse split: the agent provides judgment; the machine provides truth and a fixed bill.&lt;/p&gt;

&lt;p&gt;An important note about money: at DeepSeek's prices (with 96% cache-hit rates measured in some sessions), 100K tokens cost cents. Direct cost is not the argument. The argument is &lt;strong&gt;latency&lt;/strong&gt; (2.7s vs 38s per task), &lt;strong&gt;predictability&lt;/strong&gt; (bounded bill vs 6.6× variance), &lt;strong&gt;context degradation&lt;/strong&gt; in long sessions, and what this gap means when the model costs dollars per million instead of cents — or when the loop runs unattended in CI, with no one there to say "no" in time.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Limitations
&lt;/h2&gt;

&lt;p&gt;I declare them before the first hostile comment does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Small repo&lt;/strong&gt; (a 5–6 file mini-shop). The absolute gap would grow with repo size in both systems, but the structure of the gap (loop vs pipeline) is size-independent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A single model family&lt;/strong&gt; (DeepSeek). Nothing prevents rerunning the benchmark with other providers; the method is portable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First-round literal prompts were not preserved&lt;/strong&gt; (incident disclosed in section 4; prompts frozen since 2026-09-10).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D-Engine can't create new files&lt;/strong&gt; yet, and its file selector (P9) is non-deterministic — though the architecture absorbs the variance safely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fuzzy matching (0.85 threshold) is the weakest link&lt;/strong&gt;: the only patch that broke syntax in the entire benchmark came through that path. On the roadmap: retry with compiler feedback, and mandatory Verify when a patch only applies via fuzzy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I don't measure agent judgment quality on open-ended tasks&lt;/strong&gt; ("improve this design"), where the exploratory loop has real advantages. D-Engine is built for bounded, specifiable changes — which are most of daily work.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  9. What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v0.3&lt;/strong&gt;: new-file creation, retry with &lt;code&gt;tsc&lt;/code&gt; feedback, Verify-if-fuzzy, and time+tokens printed in the final summary (measuring time by hand with a stopwatch was the least glamorous part of this benchmark).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Published&lt;/strong&gt;: the code is MIT and lives on GitHub with the complete benchmark (frozen prompts, voided rows included) so anyone can reproduce or rebut it: &lt;a href="https://github.com/corruchaga/D-Engine" rel="noopener noreferrer"&gt;https://github.com/corruchaga/D-Engine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dsh's PTC mode&lt;/strong&gt; remains as future work: DeepSeek is already trying to collapse the loop into a single TypeScript program. If it works, it's proof the industry is converging toward this idea on its own.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Coding agents are impressive. They're also token-burning machines with unpredictable variance, no native compile gate, and a… creative relationship with your repository's actual state.&lt;/p&gt;

&lt;p&gt;This benchmark shows that for daily work — bounded, specifiable, verifiable changes — a deterministic pipeline produces &lt;strong&gt;the same quality&lt;/strong&gt; (48/50, tied with the best agent) at &lt;strong&gt;a fraction of the cost&lt;/strong&gt; (14–42× fewer tokens depending on configuration), &lt;strong&gt;a fraction of the time&lt;/strong&gt; (2.7s vs 38s), with a &lt;strong&gt;predictable bill&lt;/strong&gt; and &lt;strong&gt;zero broken commits&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We don't need a smarter model. We need a gate.&lt;/p&gt;

&lt;p&gt;The AI thinks. The gate decides.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sergi Corruchaga is a junior developer (DAM graduate, currently studying DAW). D-Engine is his first open-source project. The complete benchmark — every table, incident, and voided row — is available in the repository.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>typescript</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
