<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>JetBrains on Trevor's Blog</title><link>http://hitrevor.com/en/tags/jetbrains/</link><description>Recent content in JetBrains on Trevor's Blog</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Wed, 04 Nov 2026 21:10:00 +0800</lastBuildDate><atom:link href="http://hitrevor.com/en/tags/jetbrains/index.xml" rel="self" type="application/rss+xml"/><item><title>JetBrains' New IDE, and the Editor Is Read-Only</title><link>http://hitrevor.com/en/posts/thinkrail/</link><pubDate>Wed, 04 Nov 2026 21:10:00 +0800</pubDate><guid>http://hitrevor.com/en/posts/thinkrail/</guid><description>JetBrains shipped an AI IDE, and getting it running showed me that the feature list isn&amp;rsquo;t the interesting part: the source hardcodes readOnly: true, and when I typed into the editor the file hash didn&amp;rsquo;t move. This is an IDE that won&amp;rsquo;t let you change code.</description><content:encoded><![CDATA[<p>JetBrains released something new on August 19, 2026, called ThinkRail, and almost nobody in the Chinese tech circles has written about it.</p>
<p>I read the repo before I installed the local build. Reading the source turned up one thing that surprised me more than any of its features: the editor in this &ldquo;IDE&rdquo; is read-only.</p>
<p>Line 110 of <code>monacoSetup.ts</code> says <code>readOnly: true</code>, with a hint string to go with it. I opened the UI and tried typing into it. Not a single character went in, and the file hash didn&rsquo;t change.</p>
<p>This post is about that one thing: an IDE that won&rsquo;t let you edit code, and what exactly it&rsquo;s betting on.</p>
<h2 id="it-isnt-the-next-intellij">It Isn&rsquo;t the Next IntelliJ</h2>
<p>The repo is at <code>JetBrains/thinkrail</code>, Apache-2.0, with a &ldquo;JetBrains incubator project&rdquo; badge on the README.</p>
<p>Their own description is one sentence: use pi to do vibe coding in this lightweight IDE, and it customizes itself around the way you work.</p>
<p>What&rsquo;s pi? A third-party minimal agent harness, package name <code>@earendil-works/pi-coding-agent</code>, from the Earendil folks. Its philosophy is &ldquo;no features, just primitives&rdquo;. Sub-agents, plan mode, permission prompts, none of it is built in. You write your own extensions.</p>
<p>What ThinkRail does is wrap that command-line agent in a full interface: workspace, editor, diff, terminal, spec tree.</p>
<p>So what you&rsquo;re looking at is a company of a couple thousand people writing a shell in TypeScript to wrap an agent that somebody else wrote. That&rsquo;s a different road from the one IntelliJ took with its own kernel.</p>
<p><img loading="lazy" src="/images/thinkrail/fig1.png"></p>
<h2 id="installing-it-means-a-218-mb-file">Installing It Means a 218 MB File</h2>
<p>It comes in two shapes: a desktop installer, and a self-contained command line build.</p>
<p>I downloaded the CLI version. A single 218 MB file with a Bun runtime stuffed inside, so you don&rsquo;t have to install node first. Running it looks like this:</p>
<p><code>./thinkrail --no-open --port 24242 &lt;your repo path&gt;</code></p>
<p>Open <code>localhost:24242</code> in a browser and you get the full interface. There&rsquo;s no account system of its own. Models come from pi&rsquo;s config.</p>
<p>I was all set to go into settings and paste a DeepSeek key, and then the Providers page opened with a line already sitting there: DeepSeek, env key <code>DEEPSEEK_API_KEY</code>, connected.</p>
<p>It had read the connection pi already had configured in my shell environment. Zero setup.</p>
<h2 id="i-gave-it-a-broken-repo">I Gave It a Broken Repo</h2>
<p>I prepared the test case on purpose: a small JS library that turns titles into URL slugs, with one of its two tests red because the implementation doesn&rsquo;t handle punctuation.</p>
<p>The landing page has three options: write specs, start work directly, or work inside the project directory. I clicked the first one, which is its signature flow.</p>
<p>I kept the prompt restrained: write out the specs as things stand, don&rsquo;t change any code yet.</p>
<p>After I hit create, the first thing it did was cut a real git worktree at <code>~/.thinkrail/worktrees/demo-repo/workspace-1</code>, on a branch called <code>write-slug-lib-specs</code>. I went back to the main repo to check. <code>main</code> was still on the same commit, not a hair moved.</p>
<p>This step isn&rsquo;t simulated. <code>git worktree list</code> shows two lines.</p>
<h2 id="six-minutes-seventeen-seconds-three-files">Six Minutes Seventeen Seconds, Three Files</h2>
<p>When it finished I looked at the numbers: 6 minutes 17 seconds, 26 tool calls, 15 steps, with three <code>spec_create</code>, three file reads, and three file edits. It used 5.3% of a one million token context and cost 0.138 dollars.</p>
<p>It didn&rsquo;t start writing right away. First <code>ls</code> to see the structure, read the README, read the tests, then it actually ran <code>node --test</code>, saw that red test, and only then started writing.</p>
<p>Three markdown files came out:</p>
<p><code>goal-and-requirements.md</code> covers what the library is, who it&rsquo;s for, and that for now it only does &ldquo;lowercase plus spaces to hyphens&rdquo;. <code>architecture.md</code> covers the single-module topology, with dependencies going only from tests to source. <code>src/SPEC.md</code> covers the <code>slugify</code> contract and its boundaries.</p>
<p>All three carry frontmatter, <code>id</code>, <code>type</code>, <code>status: draft</code> and <code>parent</code>, strung together into a graph. That&rsquo;s not a format I taught it. It&rsquo;s the fixed rule from the <code>spec-graph</code> skill pack it loads.</p>
<p>The most interesting part is how it handled that red test. It didn&rsquo;t write &ldquo;strips punctuation&rdquo; down as a capability that already works. Instead it opened a separate section in the module spec called &ldquo;Known limitation&rdquo; and spelled it out: the test expects <code>hello-world</code>, the function returns <code>hello,-world!</code>, punctuation left as is.</p>
<p>When it was done it ran <code>spec_validate</code> itself. It passed.</p>
<p><img loading="lazy" src="/images/thinkrail/fig2.png"></p>
<h2 id="what-the-spec-graph-looks-like">What the Spec Graph Looks Like</h2>
<p>The three files aren&rsquo;t documents sitting side by side. They&rsquo;re a tree with <code>parent</code> pointers.</p>
<p>The root is the goal document, the middle is architecture, the leaves are specs for individual modules. The right column in the UI is that tree. Click a node and the editor on the left renders the file, with Preview and Source views.</p>
<p>Their blog post &ldquo;Spec-Driven Development&rdquo; says the point is to let intent outlive the session. Close the chat and the code is still there, but the &ldquo;why it&rsquo;s written this way&rdquo; usually disappears along with the chat. Specs keep that part around, and the agent reads the whole graph in at the start of every run.</p>
<p>This time I only had it write, not edit. When it does edit, it reads the same graph.</p>
<p><img loading="lazy" src="/images/thinkrail/fig3.png"></p>
<h2 id="then-i-found-the-read-only-thing">Then I Found the Read-Only Thing</h2>
<p>After it finished I wanted to change a sentence myself, so I clicked into the Source view of <code>src/SPEC.md</code>, selected a line, and pressed a key.</p>
<p>Nothing. I assumed it was a focus problem, clicked a few times, then tried shoving text straight into the editable region with devtools. Same conclusion: input doesn&rsquo;t go in, and the file hash on disk is identical before and after.</p>
<p>So I went back to the source for the answer, and it&rsquo;s that <code>readOnly: true</code> from the top of this post. The UI even has a hint prepared, telling you to have the agent make the change.</p>
<p>Someone raised this on Hacker News, saying the chat panel is the lead actor in ThinkRail and the editor and file tree are supporting cast, that &ldquo;you&rsquo;re not even allowed to edit files by hand&rdquo;.</p>
<p>I checked it, and it&rsquo;s true. In fairness though: the terminal works. There&rsquo;s a real PTY at the bottom, and nobody stops you from running <code>vim</code> in it. Only that Monaco panel is locked.</p>
<p>The problem is that this design swaps out the subject of &ldquo;changing code&rdquo;. In an old IDE, you and the agent each own half of that. Here the division of labor is clear: the agent writes, you review.</p>
<p><img loading="lazy" src="/images/thinkrail/fig4.png"></p>
<h2 id="why-it-dares-to-design-it-this-way">Why It Dares to Design It This Way</h2>
<p>Because in its architecture, the IDE part was never the point.</p>
<p>The official architecture doc splits the system into three rings: the engine host, the protocol line, and the UI client.</p>
<p>The first ring runs in <code>packages/server</code>, using Bun to start an HTTP + WebSocket service with pi running in-process. The second ring is the versioned protocol in <code>packages/contracts</code>, the only coupling between the two ends. The third ring is <code>apps/web</code>, a React client that is mobile first.</p>
<p>&ldquo;Mobile first&rdquo; is not a figure of speech. The doc says so: the UI ships independently of the host, dials into a host over the network, and a phone can connect through Tailscale.</p>
<p>So from day one it never designed itself as a traditional IDE. It&rsquo;s a remote panel for an agent host, and the desktop build just happens to wrap it in Electrobun.</p>
<p>The read-only editor isn&rsquo;t a crippled editor. It&rsquo;s the natural result of that architecture: the UI is only the observer and the approver, and the thing that actually does the work is the agent inside the host.</p>
<p><img loading="lazy" src="/images/thinkrail/fig5.png"></p>
<h2 id="the-repo-itself">The Repo Itself</h2>
<p>The codebase isn&rsquo;t small: 1,493 TypeScript files plus 349 TSX files, 354,000 lines.</p>
<p>The stack is new too: Bun runtime, React 19, Monaco 0.57 with shiki, xterm 6, Tailwind 4, TypeScript 6.0.3, Astro for the site. The desktop shell isn&rsquo;t Electron, it&rsquo;s Electrobun.</p>
<p>Community numbers: 7,484 stars, 450 forks, 365 open issues. The repo was created on July 8, 2026, and it got there in under four months. That&rsquo;s a fast pace.</p>
<p>Releases are dense too: 0.2.0 on October 18, 0.3.0 on October 29, 0.3.1 on November 1, and the nightlies are already at 0.4.0.</p>
<h2 id="two-things-that-dont-sound-good">Two Things That Don&rsquo;t Sound Good</h2>
<p>First, telemetry is on by default. <code>analyticsEnabled</code> and <code>analyticsConsentConfirmed</code> are both true in <code>config.json</code>. That <code>--no-analytics</code> launch flag only turns off &ldquo;additional usage data&rdquo;, not the basic stats, so you have to go into settings to kill those.</p>
<p>Second, JetBrains&rsquo; AI strategy is a bit scattered right now. The two Hacker News threads together have over two hundred points and over two hundred comments, and the top voted one isn&rsquo;t praise, it&rsquo;s a complaint: Air and ThinkRail are both still half finished, while the AI Assistant that actually works well got pushed to the side.</p>
<p>I agree with that one. ThinkRail feels more like a bet, an experiment. JetBrains itself hangs the incubator sign on it.</p>
<h2 id="my-call">My Call</h2>
<p>If your first reaction is &ldquo;what use is an IDE that won&rsquo;t let you edit&rdquo;, then it really wasn&rsquo;t built for you.</p>
<p>It serves a different group: people already used to letting the agent do the work, whose main job is reviewing diffs and writing specs, moving forward one session after another. For them, being able to edit is actually a burden, because when you and the agent are fighting over the same file, the conflict can only be settled by self-discipline.</p>
<p>The answer it gives is physical isolation: one worktree and one branch per workspace, so the agent&rsquo;s mess stays on its own branch, and you merge only after you&rsquo;ve reviewed it.</p>
<p>I think that idea is more thorough than &ldquo;add an AI button to the editor&rdquo;. Its bet is that the IDE of the future is mainly for review, not for writing.</p>
<p>Whether the bet is right, check back in a year. As for this version, I&rsquo;ll use it for small jobs. I won&rsquo;t use it to replace IDEA.</p>
<p>When you write code these days, is that moment of changing a file still mostly your own hands, or has it already gone to the agent? If it&rsquo;s the latter, this read-only design probably won&rsquo;t bother you.</p>
]]></content:encoded></item><item><title>The eMudhra Certificate Chain Broke, So I Audited Every JetBrains App on My Mac</title><link>http://hitrevor.com/en/posts/emudhra/</link><pubDate>Tue, 03 Nov 2026 09:10:00 +0800</pubDate><guid>http://hitrevor.com/en/posts/emudhra/</guid><description>Eight intermediate certificates with recoverable private keys, four root CAs to distrust. After following JetBrains&amp;rsquo; own guidance I found the official workaround removes two of them, my machine had all four, and not one of my three JVMs was patched.</description><content:encoded><![CDATA[<p>On October 17 a security researcher reported that eight intermediate certificates issued by eMudhra had recoverable private keys, because the entropy used to generate them was weak.</p>
<p>That means anyone who can sit in the middle of your network can sign a &ldquo;trusted&rdquo; certificate with one of those keys and impersonate the services JetBrains tools talk to.</p>
<p>JetBrains published two advisories on October 30. One covers what to do about the IDEs, the other is a status table across the product line. I read through the coverage in Chinese, and it was all paraphrase. Nobody actually went and checked their machine.</p>
<p>This post is that check, written as a manual. Everything runs locally, and nothing in here changes your configuration.</p>
<h2 id="what-the-advisory-actually-says">What the advisory actually says</h2>
<p>The affected components are the ones that run on Java: the IDEs, Toolbox, Gateway, ReSharper. They trust the trust store shipped inside the bundled JetBrains Runtime, not the macOS Keychain.</p>
<p>The advisory is blunt about one thing: updating your operating system does not protect you here.</p>
<p>The fixed JBR no longer trusts these four root certificates: emSign ECC Root CA G3, emSign Root CA G1, emSign Root CA G2, and AAA Certificate Services.</p>
<p>Under the hood that is four CVEs. CVE-2026-91403 and CVE-2026-114820 are Oracle&rsquo;s fixes inside the JBR. CVE-2026-118696 covers the embedded browser JCEF taking Chrome&rsquo;s certificate revocation list. CVE-2026-118697 covers the background service jetbrainsd and its own bundled list.</p>
<p>Three layers, each fixed separately.</p>
<p><img alt="One incident, three layers of fix: JBR, JCEF, jetbrainsd" loading="lazy" src="/images/emudhra/fig1.png"></p>
<h2 id="step-one-check-whether-your-versions-even-line-up">Step one: check whether your versions even line up</h2>
<p>Don&rsquo;t start deleting certificates. First find out which build you are running. A JetBrains <code>.app</code> carries an Info.plist, and the build number is in it.</p>
<pre tabindex="0"><code>/usr/libexec/PlistBuddy -c &#39;Print :CFBundleShortVersionString&#39; \
  &#34;/Applications/Android Studio.app/Contents/Info.plist&#34;
/usr/libexec/PlistBuddy -c &#39;Print :CFBundleVersion&#39; \
  &#34;/Applications/Android Studio.app/Contents/Info.plist&#34;
</code></pre><p>Swap the path for whichever IDE you have. Toolbox installs live under <code>~/Applications</code>.</p>
<p>On my machine:</p>
<ul>
<li>IntelliJ IDEA 2026.2.3, build IU-262.10968.63, bundled JBR 25.0.4+1-508.27</li>
<li>Android Studio 2026.2, build AI-262.9437.185.2621.16467767, JBR 25.0.3</li>
<li>JetBrains Toolbox 3.9.1, build 3.9.1.89198</li>
</ul>
<p>Cross-checking against the fixed-version list: IDEA has to be 2026.2.4 to count as fixed, and I am on 2026.2.3, one patch short. Toolbox 3.9.1 is on the list, so that one passes.</p>
<p>Android Studio is a blank spot. It is not in JetBrains&rsquo; table at all, and I could not find an equivalent Google advisory, so I checked the JBR version myself: 25.0.3, while the fixed JBR 25 builds are 635.79, 508.41, and 329.142. 25.0.3 is obviously old.</p>
<p><img alt="Four components, who is patched and who is not" loading="lazy" src="/images/emudhra/fig2.png"></p>
<h2 id="step-two-just-ask-the-trust-store-how-many-are-left">Step two: just ask the trust store how many are left</h2>
<p>Version numbers can lie. Trust stores cannot. Every JBR ships a cacerts file, and its own keytool will list it.</p>
<pre tabindex="0"><code>&#34;/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/keytool&#34; \
  -list -cacerts -storepass changeit | grep -iE &#34;emsign|comodo&#34;
</code></pre><p>Android Studio returns four lines:</p>
<ul>
<li><code>comodoaaaca [jdk]</code></li>
<li><code>emsigneccrootcag3 [jdk]</code></li>
<li><code>emsignrootcag1 [jdk]</code></li>
<li><code>emsignrootcag2 [jdk]</code></li>
</ul>
<p>All four are there. IntelliJ IDEA&rsquo;s copy is the same, all four present, 111 certificates in total.</p>
<p>There is a trap here I have to mention, because I walked into it: the alias as printed carries a space and a bracketed suffix, <code>emsigneccrootcag3 [jdk]</code>. If you type just <code>emsigneccrootcag3</code> to delete it, keytool tells you no such alias exists, even though it is sitting right there in the list.</p>
<h2 id="step-three-prove-your-fix-actually-took-effect">Step three: prove your fix actually took effect</h2>
<p>This is the step the official documentation does not have.</p>
<p>The official workaround is: copy the cacerts file, delete the affected roots, then point the IDE at the copy with a VM option. The problem is knowing whether that <code>-Djavax.net.ssl.trustStore</code> actually got loaded. A wrong path, a missing slash, a <code>~</code> that never expands, and it fails silently.</p>
<p>So I wrote a thirty-line program that asks the JVM directly: how many of these do you still trust?</p>
<p><img alt="One trust store, three states: unpatched, official workaround, all four removed" loading="lazy" src="/images/emudhra/fig3.png"></p>
<p>The key line is <code>tmf.init((KeyStore) null)</code>, which makes the JVM use its default trust store, the one that honours <code>javax.net.ssl.trustStore</code>. Then you count how many issuers in <code>getAcceptedIssuers()</code> are named emSign or AAA Certificate Services.</p>
<p>Here is what came out:</p>
<p>With no VM option, it reports 109 certificates and 4 hits. Pointed at the officially cleaned copy, 107 and 2 hits. With all four removed, 105 and 0 hits.</p>
<p>Three numbers, and the gap between &ldquo;I think I fixed it&rdquo; and &ldquo;I did fix it&rdquo; closes.</p>
<h2 id="two-things-the-advisory-does-not-tell-you">Two things the advisory does not tell you</h2>
<p>First: the official workaround removes two aliases, <code>comodoaaaca [jdk]</code> and <code>emsigneccrootcag3 [jdk]</code>.</p>
<p>But what I found on my machine was all four present, G1 and G2 included. After deleting those two, my probe still reported two hits. So if you follow the two documented steps on this machine, two eMudhra root certificates stay behind.</p>
<p>I am not in a position to explain why JetBrains listed only two. Maybe the fixed runtime handles G1 and G2 elsewhere, maybe they were being conservative. On the plain question of what is on the machine, the number is four, not two. If you want to be thorough, delete all four; I measured 105 certificates and zero hits afterwards.</p>
<p>Second: macOS&rsquo;s own system roots still contain these two.</p>
<p><code>emSign ECC Root CA - G3</code> has SHA-1 3043FA4FF257DCA0C380EE2E58EA78B23FE6BBC1, and <code>emSign Root CA - G1</code> has 8AC7AD8F73AC4EC1B5754DA540F4FCCF7CB58E8C.</p>
<p><code>security dump-trust-settings</code> shows no per-certificate distrust policy in either the system or the user domain. That does not mean macOS is letting them through, TLS has other mechanisms, but from the Keychain side at least, they are still there.</p>
<h2 id="while-you-are-at-it-scan-the-other-jvms">While you are at it, scan the other JVMs</h2>
<p>This is the part most people will miss.</p>
<p>JetBrains only speaks for its own products. But your Gradle daemon runs on some JDK, your command-line Kotlin compile uses some JDK, Homebrew installed another one, and every single one has its own cacerts, unrelated to the IDE&rsquo;s.</p>
<p>I walked every JVM on the machine that can run keytool:</p>
<ul>
<li>Homebrew OpenJDK 21.0.10, 109 certificates, all four present</li>
<li>Android Studio&rsquo;s bundled JBR 25.0.3, 109 certificates, all four present</li>
<li>IntelliJ IDEA&rsquo;s bundled JBR 25.0.4, 111 certificates, all four present</li>
</ul>
<p>Not one of them is fixed.</p>
<p>JetBrains also shipped fixed JBR builds on two jbr21 lines, 21.0.11b1163.125 and 21.0.9b1038.91. When upstream OpenJDK catches up I have no first-hand source for, so I will not draw that conclusion for you. All I can say is that the 21.0.10 on this machine still has all four.</p>
<h2 id="what-to-do">What to do</h2>
<p>The priority order is obvious: upgrade if you can, and skip the workarounds.</p>
<p>IDEA 2026.2.4 shipped on October 30; I checked the date against JetBrains&rsquo; release API. Toolbox 3.9.1 is already installed, and I checked jetbrainsd too, which runs 0.9.9728, the fixed version. So the only thing left to touch is the IDE itself.</p>
<p>If you cannot upgrade yet, the official three steps are: copy cacerts, delete the aliases with the keytool from that jbr, then add a line to Help → Edit Custom VM Options with <code>-Djavax.net.ssl.trustStore=</code> pointing at the copy.</p>
<p>The path has to be absolute. No <code>~</code>, no quotes. Get it wrong and it will not complain, it just silently does nothing. Then confirm in Settings → Server Certificates that automatically accepting untrusted certificates is off.</p>
<p>One more detail: the JCEF embedded browser&rsquo;s certificate list cannot be changed, so on 2025.2.6.4 and earlier you have to turn it off entirely with the registry key <code>ide.browser.jcef.enabled</code>. Markdown previews and notebook output stop working when you do, so remember to turn it back on after you upgrade.</p>
<p><img alt="Three paths: upgrade, workaround, or fix the background service only" loading="lazy" src="/images/emudhra/fig4.png"></p>
<h2 id="my-take">My take</h2>
<p>The thing worth remembering here is not which version got fixed. It is where your trust boundaries actually are.</p>
<p>You updated macOS, so you assume you are safe. You updated Chrome, so you assume you are safe. But the IDE carries its own trust store, Gradle has another one, and the JDK on your command line has a third. Each one needs its own fix.</p>
<p>A security advisory is written for everyone. It will never answer &ldquo;what state is this specific machine in.&rdquo; That answer only comes out if you run it yourself.</p>
<p>How many JVMs are on your machine right now? Go scan them. I would bet more than one still has all four.</p>
]]></content:encoded></item><item><title>Split One Developer Request Into Three Messages and the Agent's Cost More Than Doubles</title><link>http://hitrevor.com/en/posts/jb-taskflow/</link><pubDate>Fri, 30 Oct 2026 11:46:11 +0800</pubDate><guid>http://hitrevor.com/en/posts/jb-taskflow/</guid><description>JetBrains analyzed 4,782 real IDE sessions: splitting one request into three messages more than doubles cost and barely moves the resolve rate.</description><content:encoded><![CDATA[<p>JetBrains researchers went through 4,782 real sessions, all of them engineers talking to a coding agent inside their own IDE, about 14,000 user messages in total.</p>
<p>The conclusion in one line: the benchmarks you use to grade agents today aren&rsquo;t measuring how people actually use them.</p>
<p>In SWE-Bench Pro, 93.8% of tasks are feature additions and bug fixes, and every task arrives as one complete message. The agent sees the whole picture at once and then starts working.</p>
<p>In real sessions, feature additions are only 19%, bug fixes 26%. Together they don&rsquo;t add up to half.</p>
<p>So what&rsquo;s the rest? 6% asking how the code works, 10% general programming questions, plus planning, code review, refactoring, running commands, debugging. None of that exists in SWE-Bench Pro, because that benchmark&rsquo;s task definition has no such action as &ldquo;asking a quick question.&rdquo;</p>
<p><img alt="The same issue, two different user profiles" loading="lazy" src="/images/jb-taskflow/fig1.png"></p>
<h2 id="half-the-sessions-are-a-single-message">Half the sessions are a single message</h2>
<p>They counted every session by number of user messages.</p>
<p>50.9% of sessions have just one message, 16.2% have two, 8.8% have three, and everything from four up to five adds up to under 15%.</p>
<p><img alt="4,782 real sessions by message count" loading="lazy" src="/images/jb-taskflow/fig2.png"></p>
<p>So the rest of the analysis only looks at the 33% with at least three messages, which they call long sessions — a single message is a one-shot Q&amp;A. Inside long sessions, the breakdown looks like this: 6% asking about the project&rsquo;s own code, 10% general programming questions, and the rest scattered across planning, review, refactoring, debugging, execution — feature additions and bug fixes have been diluted down to a small slice.</p>
<p>Run SWE-Bench Pro through the same classifier and you get 55% feature additions, 39% bug fixes, 6% refactoring. That&rsquo;s it.</p>
<h2 id="three-public-corpora-three-completely-different-patterns">Three public corpora, three completely different patterns</h2>
<p>They also ran the same labeling on three public agent conversation sets.</p>
<p>SpecStory is a public export of IDE sessions. 521 of its 1,000 are long sessions, the closest to their own data, with a noticeably high share of planning.</p>
<p>DataClaw is a community-shared set of sessions, 585 long ones, almost all execution and short commands. SWE-chat is records of real users in a chat interface, 698 long sessions, predominantly execution and planning.</p>
<p>The three datasets come from different products, different users, different collection methods, so they don&rsquo;t compare volumes. But one thing is hard fact: calibrate a benchmark against any one of them and you get a different task mix, and that difference isn&rsquo;t something sample size can wash out.</p>
<p>Not even their own 4,782 count as ground truth. In their words, you have to pick a target first and then declare it; there is no default one.</p>
<p>That sentence is the whole skeleton of the study. Everyone used to assume &ldquo;building tasks from GitHub issues is what&rsquo;s real.&rdquo; This paper says no — issues are just one slice of one population. Swap the population and the data takes on a different shape, and nobody is in a position to call their own slice the standard.</p>
<h2 id="they-didnt-build-a-new-benchmark-they-retrofitted-the-old-one">They didn&rsquo;t build a new benchmark, they retrofitted the old one</h2>
<p>Building an interactive benchmark from scratch means throwing away all the repos, environments, and tests SWE-Bench has accumulated over the years. So they took another route: keep the tasks, repos, tests, and original requirements, and only rewrite the user messages.</p>
<p>The method is to split each issue into three ordered requests, with zero invented content allowed. Each request has to be actionable against the code state the previous one left behind, identifiers and code snippets stay verbatim, and after splitting another model checks for any dropped requirements. Of the 731 public SWE-Bench Pro issues, 31 failed validation, leaving 700.</p>
<p>Those 700 are the entire battlefield. Every number from here on comes from them.</p>
<p>The original issue is roughly a thousand words in one message, all crammed into a single block. After splitting it looks like this — the first sentence gives only the main symptom, edge cases wait for the second and third.</p>
<p>qutebrowser had an issue where LinkedIn wouldn&rsquo;t load, caused by an older QtWebEngine missing <code>Array.prototype.at</code>.</p>
<p>The first request just says &ldquo;fix LinkedIn failing to load on macOS with QtWebEngine 5.15.2, and catch it with a polyfill.&rdquo;</p>
<p>Only the second one adds &ldquo;it must cover versions before 6.3 that lack native support, and both positive and negative indices have to be correct.&rdquo; The third only then says &ldquo;out-of-range must return undefined, and only inject when the native method is missing.&rdquo;</p>
<p>Line the three up and the complete spec from one message has been spread into three rounds of progressive disclosure.</p>
<h2 id="they-also-injected-ask-about-the-project-itself-questions">They also injected &ldquo;ask about the project itself&rdquo; questions</h2>
<p>In real sessions, 6% is asking how the project&rsquo;s code works, and issue benchmarks have none of that. So they had a model read the repo plus a trajectory where the problem had already been solved, and generate one to three questions.</p>
<p>Each question carries two things: a reference answer, and an evidence script that actually runs. During dataset construction it&rsquo;s run against a clean repo — if it produces no evidence, or it modifies the repo, the question is dropped.</p>
<p>That rule conveniently eliminates a whole class of questions: ones whose answer isn&rsquo;t in the code (&ldquo;why was it designed this way back then&rdquo;) are physically impossible to produce.</p>
<p>The qutebrowser task later got a companion question whose answer named two config entries and touched five files.</p>
<h2 id="after-splitting-cost-doubles-scores-dont-move">After splitting: cost doubles, scores don&rsquo;t move</h2>
<p>Here&rsquo;s the most valuable part of the whole paper: four models, 700 tasks, three feeding modes, three runs of each.</p>
<p>Single-shot means throwing the original issue over as one message. Split means sending the three requests in sequence, with nothing added in between. Split plus Q&amp;A means also adding those repo questions, with an optimizer choosing where they go.</p>
<p>The result: splitting raised each model&rsquo;s cost 2.0 to 2.6 times.</p>
<p>Same repos, same tests, not a single added requirement — all the extra money went into &ldquo;requirements arriving in batches.&rdquo;</p>
<p>Scores barely moved. GPT-5.6 Terra stayed flat; the other three dropped 4 to 5 points on average, roughly the same as the variance from running the same setting three times.</p>
<p><img alt="Measured results across four models × three settings" loading="lazy" src="/images/jb-taskflow/fig3.png"></p>
<p>They also ran a control: splice the three rewritten requests back into one message and send that. All three GPT models&rsquo; cost and scores landed right back in the single-shot bucket. So the expense is in the act of sending three times, not in the rewording.</p>
<h2 id="splitting-gives-you-intermediate-checkpoints">Splitting gives you intermediate checkpoints</h2>
<p>Run one long requirement to the end and you get a single final score, with right and wrong smeared together — if you want to know which step collapsed, you have to go dig through the trajectory yourself. Split into three steps and you can run the tests after each one, scoring only against the requirements revealed so far, and the failing step is visible at a glance.</p>
<p>In an ablation over 64 tasks, the pass rate and test pass rate climbed with each request. One problem becomes several verifiable checkpoints, and diagnosis gets much clearer.</p>
<p>This is probably the only benefit of splitting. Beyond it, splitting is pure cost.</p>
<h2 id="what-it-hasnt-solved">What it hasn&rsquo;t solved</h2>
<p>They only generated two kinds of messages: split requirements, and questions about the repo. Planning, review, execution, and debugging without a fix, all of which show up in real sessions, still have no generator — and for most of them, even &ldquo;how do you automatically judge correct from incorrect&rdquo; hasn&rsquo;t been worked out.</p>
<p>One more thing: every message is frozen before the run starts. Reproducibility is real, and so is the fact that the &ldquo;user&rdquo; never changes their mind in response to the agent.</p>
<p>The research stops there. The things they listed as not done go on for a while, right down to admitting a weakness like &ldquo;the classifier has no human-labeled accuracy set.&rdquo;</p>
<h2 id="what-this-means-if-you-write-code">What this means if you write code</h2>
<p>When you look at a model leaderboard, you assume that number means &ldquo;how good it is at writing code.&rdquo; What this paper says is that the number also contains something you&rsquo;ve never been choosing: the pace at which it&rsquo;s asked to work.</p>
<p>Same model, requirements delivered all at once versus in three batches — more than double the cost, roughly the same score. So how you ask for things on your own project is a separate question, and it&rsquo;s the one you control. My habit is to write background, goal, and constraints all in one message. Reading this hasn&rsquo;t changed my mind. When cost actually becomes the sticking point, the first thing I look at is how many extra steps it took, not whether it got the answer right.</p>
<p>One fun corollary: if every benchmark measures &ldquo;everything delivered at once,&rdquo; the models being trained will get used to that pace too, and then nobody can measure the follow-up questions, the course corrections, the progressive disclosure that real sessions are full of.</p>
<p>Think back to your last few agent sessions — how many were solved in one message, and how many took several rounds back and forth?</p>
]]></content:encoded></item></channel></rss>