<?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>Tech on Trevor's Blog</title><link>http://mings.in/en/tags/tech/</link><description>Recent content in Tech on Trevor's Blog</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Fri, 16 Oct 2026 08:29:21 +0800</lastBuildDate><atom:link href="http://mings.in/en/tags/tech/index.xml" rel="self" type="application/rss+xml"/><item><title>IDEA's Intelligence Is Now Inside VS Code: A 1.0 Hands-On</title><link>http://mings.in/en/posts/lsp-idea/</link><pubDate>Fri, 16 Oct 2026 08:29:21 +0800</pubDate><guid>http://mings.in/en/posts/lsp-idea/</guid><description>Completion is guesswork, go-to-definition is luck, and you do not dare press rename. On October 15, JetBrains turned the Java and Kotlin engine from IntelliJ IDEA into a language server extension and shipped 1.0, installable in VS Code, Cursor, and Google Antigravity.</description><content:encoded><![CDATA[<h2 id="writing-kotlin-in-vs-code-has-always-been-a-compromise">Writing Kotlin in VS Code has always been a compromise</h2>
<p>Completion is guesswork, go-to-definition is luck, and you do not dare press rename. On October 15, JetBrains turned the Java and Kotlin engine from IntelliJ IDEA into a language server extension and shipped 1.0, installable in VS Code, Cursor, and Google Antigravity.</p>
<p>Below, VS Code means Visual Studio Code and IDEA means IntelliJ IDEA.</p>
<p>I ran it against an Android project on this machine for a full pass. The engine really is IDEA&rsquo;s. But there is one condition you should know up front: the intelligence is not in the editor, it is in a server the extension downloads for itself after launch, and that server wants a license.</p>
<h2 id="what-it-actually-delivers">What it actually delivers</h2>
<p>The capability list from the official 1.0 release notes, plus what the extension itself reports, gives you this in practice:</p>
<ul>
<li>One index across mixed projects. Java, Kotlin, and projects mixing both are all understood, and jumping to a definition on the other side does not break the chain. That means no more installing three or four language plugins at once, and no more worrying about them fighting each other.</li>
<li>Completion, navigation, inspections, quick fixes, rename, formatting. These are the highest-frequency moves day to day, and they are this extension&rsquo;s selling point.</li>
<li>Maven, Gradle, and Bazel are all understood, JUnit runs, and large repos do not choke.</li>
<li>A debugger with simulated breakpoints and async call stacks, which is useful for coroutine-heavy code.</li>
<li>Cursor&rsquo;s Agents Window gets dedicated support: it can be given its own language server instance so the agent gets analysis built on IDEA&rsquo;s inspections, including JSpecify null-safety and special handling for the Spring framework.</li>
<li>The language server also ships an MCP server, built with ktor&rsquo;s SSE and the MCP Kotlin SDK. The team does not promote this much, but for anyone who wants agents to consume code intelligence directly, it is a new path.</li>
</ul>
<p>One recommendation worth following: it overlaps with the Java extensions from Red Hat and Oracle on inspections and quick fixes, and the team explicitly recommends disabling those two when running both. Spring Tools does not conflict and can stay.</p>
<h2 id="installing-takes-one-command">Installing takes one command</h2>
<p>Set expectations first: the package you download from the marketplace is only 1.4 MB. The actual intelligence is downloaded at runtime.</p>
<p><img alt="Extension shell versus language server: 1.4 MB against 361 MB" loading="lazy" src="/images/lsp-idea/fig1-shell-vs-server.png"></p>
<p>So &ldquo;install a plugin&rdquo; is split into two halves: a shell in the editor, and 361 MB on JetBrains&rsquo;s servers. The shell holds only commands, settings, and grammar files — not one line of language analysis code. The unpacked server takes 1.2 GB and bundles its own JetBrains Runtime 25.</p>
<p>For a command-line install, VS Code looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">code --install-extension JetBrains.intellij-server --force
</span></span><span class="line"><span class="cl">code --list-extensions --show-versions
</span></span><span class="line"><span class="cl"><span class="c1"># jetbrains.intellij-server@1.0.27</span>
</span></span></code></pre></div><p>1.0.27 shipped packages for six platforms — Apple silicon, Intel, two for Linux, two for Windows — all released on the same day, October 15. Editors like Cursor pull from Open VSX; VS Code pulls from Microsoft&rsquo;s marketplace.</p>
<h2 id="of-those-43-settings-only-a-few-are-worth-touching">Of those 43 settings, only a few are worth touching</h2>
<p>The extension adds 43 settings to the editor, and the overwhelming majority should stay at defaults. These are the ones I would change:</p>
<table>
	<thead>
			<tr>
					<th>Setting</th>
					<th>Default</th>
					<th>When to change it</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>intellij.jdkForSymbolResolution</td>
					<td>empty</td>
					<td>When the JDK used for symbol resolution is not the one the project runs on, point at the path here</td>
			</tr>
			<tr>
					<td>intellij.additionalJvmArgs</td>
					<td>empty</td>
					<td>When analysis on a large project is starved, add JVM flags like -Xmx</td>
			</tr>
			<tr>
					<td>intellij.buildTool</td>
					<td>auto-detect</td>
					<td>When you want to pin Gradle or Bazel in a multi-module repo</td>
			</tr>
			<tr>
					<td>intellij.workspace.reloadOnBuildFileSave</td>
					<td>always</td>
					<td>Re-imports every time you save a build file; switch to manual if that gets noisy</td>
			</tr>
			<tr>
					<td>intellij.projects</td>
					<td>empty</td>
					<td>When one workspace holds several projects and you do not want them seeing each other</td>
			</tr>
			<tr>
					<td>intellij.dev.serverPort</td>
					<td>-1</td>
					<td>When a server is already running and you want the editor to connect to it instead of starting another</td>
			</tr>
			<tr>
					<td>intellij.trace.server</td>
					<td>off</td>
					<td>When you want to see what actually goes back and forth between editor and server</td>
			</tr>
	</tbody>
</table>
<p>That last one deserves a note. The default of -1 means &ldquo;start one myself&rdquo;; set a port number and it becomes &ldquo;connect to that one.&rdquo; The switch existing at all tells you the team designed this language server as a standalone process, and the editor is just its first client.</p>
<h2 id="so-i-skipped-the-editor-and-talked-to-the-server-directly">So I skipped the editor and talked to the server directly</h2>
<p>If it is a standalone process, there is no reason to go around it. The installed package has an executable called intellij-server. Start it and read the flags — the surface is bigger than what the editor exposes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./bin/intellij-server --help
</span></span><span class="line"><span class="cl"><span class="c1"># --stdio                     stdio mode, for editors</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --socket=127.0.0.1:9999     server mode, default port 9999</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --port-file=&lt;path&gt;          write the bound port to a file so clients can find it</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --idle-timeout=10m          exit when no client is connected</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --multi-client              allow multiple clients at once</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --data-sharing=none         turn telemetry off</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --system-path=&lt;path&gt;        where caches and indexes go</span>
</span></span></code></pre></div><p>One more detail is fun: first launch asks you for a EULA hash, and that hash is the first 16 characters of the SHA-256 of the EULA.txt in the package. What it is asking you to confirm is &ldquo;I agree to this version of the terms.&rdquo; Change the terms and the hash changes.</p>
<p>I wrote a hundred-line Python client and spoke the LSP protocol at it directly:</p>
<p><img alt="Real output from talking to the language server directly" loading="lazy" src="/images/lsp-idea/fig2-lsp-refused.png"></p>
<p>The handshake took 1.4 seconds. It reports itself as IntelliJ Language Server by JetBrains, version ILS-263.7084.0, corresponding to the 2026.3 platform. It reported back 25 capability keys, 22 of them Providers: completion, navigation, rename, inlay hints, semantic highlighting, type hierarchy, call hierarchy are all there.</p>
<p>Then I asked it to import that Android project on this machine, and it actually did it. The log listed the Gradle model item by item, from ModuleSourceSets to AndroidProject, ending with Successfully imported.</p>
<p><img alt="Cold start timeline and memory use" loading="lazy" src="/images/lsp-idea/fig3-cold-start.png"></p>
<p>Numbers, for the record: the first import (Gradle daemon has to start, dependencies have to resolve) took 21 seconds; with the daemon and caches warm, an import takes 978 milliseconds, and 10.5 seconds from process start to ready. On memory, the language server itself is 626 MB, and the Gradle daemon it spawns adds another 914 MB — and the daemon survives after you shut the server down, waiting out a three-hour idle timeout before exiting.</p>
<h2 id="here-is-the-wall-no-license-no-answers">Here is the wall: no license, no answers</h2>
<p>All of the above is the good part. Now the thing nobody tells you before you install.</p>
<p>The server is up, the project is imported, the ready notification has been sent. Then I request a completion and get this back:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;code&#34;</span><span class="p">:</span> <span class="mi">-32802</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;message&#34;</span><span class="p">:</span> <span class="s2">&#34;Request refused: no active JetBrains license.&#34;</span><span class="p">}</span>
</span></span></code></pre></div><p>Hover, document symbols, go-to-definition, one after another — same code, same sentence every time. It can connect, compute, and import. It just will not hand you the results. A quick license status query gives its side of it: not licensed, feature requests are parked.</p>
<p>The team is blunt about it in the release notes:</p>
<blockquote>
<p>With version 1.0, the extension moves out of its free preview phase. Using it now requires an IntelliJ IDEA Ultimate subscription after a 30-day trial period during which you can try out its full feature set for free.</p>
</blockquote>
<p>The same notes have a line worth more attention:</p>
<blockquote>
<p>The license is explicitly designed for human use; we&rsquo;ll release an update regarding licensing models for purely agentic use soon.</p>
</blockquote>
<p>In plain terms, the license is granted for human use, and the rules for agent-only use will be announced later. Which is an admission that this part is not settled.</p>
<p>They do give you the commands for unlocking it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./bin/intellij-server license login      <span class="c1"># JetBrains account; --code mode suits environments without a browser</span>
</span></span><span class="line"><span class="cl">./bin/intellij-server license activate &lt;activation code / license file / floating license server&gt;
</span></span><span class="line"><span class="cl">./bin/intellij-server license trial      <span class="c1"># anonymous 30-day trial</span>
</span></span></code></pre></div><p>You can also feed a key straight in through the INTELLIJ_SERVER_LICENSE environment variable, but it only lives in memory and is gone on restart. In other words, this layer is not a toggle inside the editor. It is a server with its own license state.</p>
<h2 id="a-few-traps-you-will-genuinely-hit">A few traps you will genuinely hit</h2>
<ul>
<li>That 361 MB is downloaded by the server, not by you. When the download fails the editor only shows a vague notification; the real error is in the server&rsquo;s own log, and the log path is printed on first launch.</li>
<li>It spawns a Gradle daemon for your project, using the Gradle wrapper already in your project. First time you open a large project, do the memory math as &ldquo;server plus daemon,&rdquo; not just 626 MB.</li>
<li>The extension requires VS Code 1.105.1 or newer and Node 22.20 or newer. Older versions will not install it.</li>
<li>The day your license expires there is no loud noise. Syntax highlighting stays, because the editor&rsquo;s own grammar files handle that, but completion, navigation, and refactoring all go quiet together.</li>
</ul>
<h2 id="closing">Closing</h2>
<p>This extension changed one of my assumptions. I used to think of an IDE&rsquo;s language intelligence as part of the editor. Now it looks more like a subscription service, with the client as a shell. JetBrains played this smartly: sell one engine once inside its own IDE, and sell it again inside other people&rsquo;s editors. For developers, the cost is one more server to keep an eye on.</p>
<p>What Kotlin plugins are in your editor right now, and would this make you swap them out? Talk in the comments.</p>
]]></content:encoded></item><item><title>A Patch That Saved 15 MiB Got Rejected, and the Reason Was Not in the Code</title><link>http://mings.in/en/posts/kn-outliner/</link><pubDate>Fri, 09 Oct 2026 08:10:57 +0800</pubDate><guid>http://mings.in/en/posts/kn-outliner/</guid><description>An engineer was doing size optimization on his own iOS build and found that one extra compiler flag shrank the bundle by 15 MiB. He filed an issue with a reproduction on a public project and data from real devices, and opened a pull request that same night.</description><content:encoded><![CDATA[<p>An engineer was doing size optimization on his own iOS build and found that one extra compiler flag shrank the bundle by 15 MiB. He filed an issue with a reproduction on a public project and data from real devices, and opened a pull request that same night.</p>
<p>The next morning the PR was closed. No technical review.</p>
<p>The reason given: they do not accept low-effort AI-generated contributions. To feel the weight of that sentence, you have to read the technical part first.</p>
<h2 id="what-he-found-small-binary-mode-never-touches-kotlin-code">What he found: small-binary mode never touches Kotlin code</h2>
<p>The subject is <code>smallBinary</code>, an experimental option in Kotlin/Native since 2.2.20. It switches the IR pipeline&rsquo;s optimization level to Oz and stops forcing inlining of runtime hot paths. Sounds like everything that should be cut gets cut.</p>
<p>But for the final code generation step, Kotlin/Native still runs <code>clang -cc1 ... -O3</code>. That value lives in the toolchain&rsquo;s <code>konan.properties</code> under the key <code>clangOptFlags.ios_arm64</code>.</p>
<p>And LLVM&rsquo;s MachineOutliner, the pass that removes duplicate machine code, only applies by default to functions tagged with the <code>minsize</code> attribute on AArch64.</p>
<p>Stack the two: the IR layer is in size mode, the machine code layer is still in performance mode, and functions Kotlin generates carry no <code>minsize</code>. The result is that MachineOutliner sweeps through and touches zero Kotlin functions.</p>
<p>He put two sets of numbers in the issue. Of the 33,881 function definitions in the final bitcode, only 55 carry <code>minsize</code>, all of them runtime cold paths. In their app, the object holding 33 MB of Kotlin code has 11 outline helpers; the precompiled Skia object next to it has 4,459.</p>
<h2 id="i-ran-it-myself">I ran it myself</h2>
<p>You should not take someone else&rsquo;s numbers on something like this. I had Kotlin/Native 2.4.0 locally, wrote a small chunk of interface-dispatch-heavy code, 300 functions, and compiled the same source file three times, all with <code>-opt</code> and <code>-Xbinary=smallBinary=true</code>.</p>
<p><img loading="lazy" src="/images/kn-outliner/terminal.png"></p>
<p>The mechanism reproduced completely. By default there are only 9 outline helpers, which shows the pass really is skipping Kotlin code. Add one konan.properties override and the helper count goes into the thousands, with size dropping in step. Absolute size only fell 5% to 9%, because my sample project is tiny while his Kotlin object is tens of MB.</p>
<p>My local konan.properties does indeed contain <code>clangOptFlags.macos_arm64 = -O3</code> and <code>llvmInlineThreshold = 100</code>, so both premises of his argument check out.</p>
<h2 id="the-size-saved-and-the-other-side-of-the-ledger">The size saved, and the other side of the ledger</h2>
<p>His app is a Compose Multiplatform iOS build, unsigned archive at 114.7 MiB (same commit, Kotlin 2.4.10, Xcode 26.5).</p>
<pre tabindex="0"><code>smallBinary + latin1Strings         114.7 → 101.7 MiB
plus forcing the outliner on         → 86.9 MiB
plus inline threshold 5              → 81.4 MiB
</code></pre><p>That 81.4 MiB in step three deserves a closer look: he built 81.3 MiB using a patched compiler that tags every Kotlin function with minsize, and the two differ by 0.1 MiB. In other words most of that gain comes from less inlining, and you can get it without touching the compiler.</p>
<p>He also spelled out the costs. A 23-second scripted scroll on iPhone 13 pushed CPU from 8.48s to 8.94s, up 5.4%, and janky frames from 18 to 27; on iPhone X CPU rose 6.5%. Startup time unchanged.</p>
<p>The counterintuitive one is download size. The whole executable, gzipped, went from 20.42 MB to 20.05 MB. It moved 0.37 MB. The unsigned bundle lost 14.8 MiB and compressed almost not at all, because the duplication being removed is exactly what a compression algorithm likes to eat.</p>
<p>Also, framework code generation time went from 2 minutes to 6. And the top of a crash stack gains an <code>OUTLINED_FUNCTION_n</code> frame, though lldb still walks back to the real caller — he tested Kotlin exceptions and SIGSEGVs on both builds and the logical stack matched.</p>
<p>His own situation was a finance app, and his conclusion was that he would rather have smooth scrolling than save those 15 MiB. The two binary options were in review; the outliner one waits until his heaviest page is device-tested.</p>
<h2 id="then-jetbrains-closed-his-pr">Then JetBrains closed his PR</h2>
<p>Technical part done. Now the rejection.</p>
<blockquote>
<p>We don&rsquo;t accept low-effort AI-generated contributions that shift the burden of understanding, verifying, and fixing the proposed changes onto maintainers.</p>
</blockquote>
<p>In other words: they do not accept low-effort AI-generated contributions that move the burden of understanding, verifying and fixing onto maintainers. There was a follow-up line too: using AI tools is fine, but contributors have to put in their own engineering effort and take responsibility for the quality and correctness of what they submit.</p>
<p>His own retrospective in the post is candid. He admits he used AI tools to prepare the PR, opened it before the team had looked at the issue, then rewrote it an hour later. From his side it was one rushed move; from the maintainer&rsquo;s side it was the kind of drive-by submission they get buried in every day.</p>
<p>He does draw one boundary: the PR being closed does not overturn the technical conclusion. Those numbers reproduce with one flag and a stock compiler, and the public KotlinConf app gives anyone an independent way to check. Worth mentioning: that public app&rsquo;s Kotlin object went from 14.88 MB to 8.33 MB.</p>
<p>The issue is now marked Declined, created October 7, updated the next day.</p>
<h2 id="what-people-writing-kotlinnative-can-do-now">What people writing Kotlin/Native can do now</h2>
<p>If your project ships an iOS framework, do these three things in order.</p>
<p>First, turn on the <code>smallBinary</code> and <code>latin1Strings</code> binary options. They work with a stock compiler, both are experimental, and remember to retest on every Kotlin upgrade. That step got him 13 MiB.</p>
<p>To push further you go down the konan.properties override path: force the outliner on, push the inline threshold down. It does pay off, but it is undocumented usage. What is officially documented is <code>-Xllvm-module-passes</code> and <code>-Xllvm-lto-passes</code>, and KT-69212 says you cannot currently disable a specific pass outright.</p>
<p>That kind of override has a hidden risk: if a release renames the property, it silently stops working. So put a size check in CI.</p>
<p>Finally, always device-test performance before shipping. This optimization trades CPU for size, and his measured scroll cost starts at 5% and up.</p>
<p>A few items he also tested that did not pan out:</p>
<ul>
<li>A vendor&rsquo;s Swift package pulled in a 4.9 MiB OpenSSL framework that was never used; check with <code>otool -L</code> plus <code>nm</code></li>
<li>The ICU data Skiko ships is 6.3 MB; he trimmed a build and long-pressing the input field crashed outright, so he stopped there</li>
<li><code>material-icons-extended</code> is declared in several modules but not one byte of it reached the bundle; removing it only saves build time</li>
<li><code>@Preview</code> functions are stripped in release anyway</li>
<li>LLVM&rsquo;s famous global function merging pass actually made the Kotlin object 0.44 MB larger under his configuration</li>
</ul>
<h2 id="last">Last</h2>
<p>What is interesting here is not those 15 MiB. A reproducible performance problem, a public reproduction project, a set of on-device measurements — with all of that assembled, what stopped it was not a technical dispute. It was the trust cost inside the contribution process.</p>
<p>For people who write code it is a reminder: let maintainers evaluate the issue first, do not rush to open the PR. For maintainers it is a different question: AI has pushed the cost of producing a PR to nearly zero while review cost has not dropped at all. More projects are going to draw this line.</p>
<p>Would you take a 5% scroll cost to save 15 MiB? Tell me in the comments.</p>
<p>References:</p>
<ul>
<li>Mo Yaver&rsquo;s detailed write-up <a href="https://medium.com/@mhammadjaber00/kotlin-natives-smallbinary-never-runs-llvm-s-outliner-on-kotlin-code-f457d0fbb6d2">https://medium.com/@mhammadjaber00/kotlin-natives-smallbinary-never-runs-llvm-s-outliner-on-kotlin-code-f457d0fbb6d2</a></li>
<li>The issue he filed, KT-90068 <a href="https://youtrack.jetbrains.com/issue/KT-90068">https://youtrack.jetbrains.com/issue/KT-90068</a></li>
<li>The closed PR #8802 <a href="https://github.com/JetBrains/kotlin/pull/8802">https://github.com/JetBrains/kotlin/pull/8802</a></li>
<li>Kotlin 2.2.20 release notes (smallBinary and latin1Strings) <a href="https://kotlinlang.org/docs/whatsnew2220.html">https://kotlinlang.org/docs/whatsnew2220.html</a></li>
<li>Kotlin/Native binary options docs <a href="https://kotlinlang.org/docs/native-binary-options.html">https://kotlinlang.org/docs/native-binary-options.html</a></li>
<li>Custom LLVM optimization passes <a href="https://kotlinlang.org/docs/native-llvm-passes.html">https://kotlinlang.org/docs/native-llvm-passes.html</a></li>
</ul>
]]></content:encoded></item><item><title>Are the Big Three Back in the Game?</title><link>http://mings.in/en/posts/ai-trio/</link><pubDate>Thu, 01 Oct 2026 07:46:19 +0800</pubDate><guid>http://mings.in/en/posts/ai-trio/</guid><description>First reaction: &amp;ldquo;oh, finally.&amp;rdquo;</description><content:encoded><![CDATA[<h2 id="saw-gemini-4-this-morning">Saw Gemini 4 this morning</h2>
<p>First reaction: &ldquo;oh, finally.&rdquo;</p>
<p>Second reaction: &ldquo;I can&rsquo;t use it anyway.&rdquo;</p>
<p>On September 30, Google&rsquo;s blog published Gemini 4 Argon, bylined to Koray Kavukcuoglu, senior VP at Google DeepMind. It hit the Hacker News front page the same day. The opening line is restrained:</p>
<blockquote>
<p>Today, we&rsquo;re announcing our new frontier model, Gemini 4 Argon, which is rolling out to a set of trusted cyber defenders through our Fairwind Program.</p>
</blockquote>
<p>Which translates to: it goes to a batch of trusted cyber defenders first. Not to you.</p>
<p>I know this road well. This is how model vendors have shipped frontier capability for years. First the US government&rsquo;s voluntary pre-deployment evaluation, then a small circle of trusted testers, and only then developers, enterprises and ordinary users. The post even spells out the order: &ldquo;starting with paid API customers and Google AI Ultra subscribers&rdquo;.</p>
<p>So the accurate statement is not &ldquo;Gemini 4 shipped&rdquo;. It is &ldquo;Gemini 4 was announced, and a small batch went out.&rdquo;</p>
<h2 id="right-now-you-really-cant-use-it">Right now you really can&rsquo;t use it</h2>
<p>I didn&rsquo;t want to get anyone&rsquo;s hopes up, so I checked two places myself.</p>
<p>First, Google&rsquo;s own developer docs. On the Gemini API model list page (marked updated September 24), the newest entries are still Gemini 3.8 Flash, 3.8 Live, 3.8 Flash TTS. No argon endpoint. Which means even with an API key you can&rsquo;t call it.</p>
<p>Second, prediction markets. Polymarket runs a &ldquo;when will Gemini 4.0 launch&rdquo; market with $880K in volume and rules written in stone:</p>
<blockquote>
<p>For this market to resolve to &ldquo;Yes,&rdquo; Gemini 4.0 must be launched and publicly accessible&hellip; A closed beta or any form of private access will not suffice.</p>
</blockquote>
<p>A closed beta doesn&rsquo;t count. There has to be a publicly reachable entry point. So on that market, September 30 sits at 1%, October 15 at 68%, October 31 at 88%, November 30 at 94%. Bettors putting real money down are saying they don&rsquo;t think that day counted as a launch.</p>
<p>Put the two together and the weight of this gets clear. The cards are face up, but they&rsquo;re still in Google&rsquo;s hand.</p>
<h2 id="what-argon-actually-puts-on-the-table">What Argon actually puts on the table</h2>
<p>Can&rsquo;t use it, but the post carries a lot. Here&rsquo;s what I pulled out.</p>
<p>Output cap raised to 1M tokens. The post says from 64K to 1M, and calls it &ldquo;industry-leading&rdquo;. This matters more than it sounds: a model that can write hundreds of thousands of tokens in one go turns &ldquo;long-horizon task done in one shot&rdquo; from a demo into something you can configure.</p>
<p>A whole row of benchmarks. 77.9% on DeepSWE v1.1, which the post calls the new SOTA on real-world, long-horizon software engineering tasks. 51.3% on AutomationBench, first place in Zapier&rsquo;s end-to-end business workflow eval. 91.7% on LVBench for long-video understanding. 68% on CWE-bench v1 for vulnerability repair, tied for first.</p>
<p>It also name-checks Vals Index, Vals Finance Agent v2 and Harvey&rsquo;s legal agent benchmark, all framed as leading.</p>
<p>Pricing pinned right up against competitors. Introductory $2 per million input tokens, $10 output, 95% off cached input, back up to $4 and $20 after the intro window.</p>
<p>The most concrete part is how Google itself uses it. Three internal cases, and I find them more meaningful than the benchmarks: the quantum computing team used it to optimize subroutines, beating the published baseline by 40%; a set of agents analyzed fleet-wide performance data for memory optimization, freeing 300 TiB up front with 500 TiB to 1 PiB expected at the end.</p>
<p>Then large-scale C/C++ to Rust migration, from re2 and libgav1 all the way to Fuchsia&rsquo;s Zircon kernel, over 800,000 lines. The libgav1 case is specific: the agent converted 32,000 lines of SIMD code into safe Rust that runs 2.7x faster than the existing Rust port.</p>
<p>Security it lays out fairly openly. The build for trusted defenders ships without cyber guardrails so they get the full attack surface. The public build emphasizes protection against indirect prompt injection (claimed leading on Gray Swan&rsquo;s IPI benchmark), plus mismatch monitoring over chain of thought and actions. Wiz already used it to find a high-severity vulnerability in medical software used by hospitals worldwide, one that a previous frontier model missed.</p>
<h2 id="what-everyone-else-was-doing-the-same-day">What everyone else was doing the same day</h2>
<p>This is where the &ldquo;big three&rdquo; line comes from. This half month was not a solo Google show.</p>
<p>Timeline first. Anthropic shipped Fable 5.1 and Mythos 5.1 on September 1, then Opus 5.5 on September 22 — one line summary: &ldquo;matches Fable 5.1, 40% cheaper than Opus 5&rdquo;. Then Sonnet 5.5 on September 28, &ldquo;30% faster, up to 30% cheaper on most work&rdquo;.</p>
<p>On OpenAI&rsquo;s side, September 30 (same day) brought GPT-6.1 Sol, with a subtitle blunter than Google&rsquo;s:</p>
<blockquote>
<p>Near-Astra intelligence for a fifth of the price</p>
</blockquote>
<p>Near-Astra intelligence at a fifth of the price. $2 per million input, $10 output, $0.10 cached input. A few concrete numbers: matches Astra on DeepSWE v1.1 at a fifth of the cost; beats Opus 5.5 on GDP.pdf at less than half the cost per task.</p>
<p>On Terminal-Bench Science, the scientific workflow benchmark, it costs $5.47 per task. Opus 5.5 is $23.21, Astra is $23.80.</p>
<p>You may have noticed something already. Google and OpenAI both report DeepSWE v1.1 and AutomationBench, and both landed cached input at $0.10. Benchmark framing and pricing framing converging at the same time means both are staring at the same customers.</p>
<p>Now look at what each of them has been filling in. Since Gemini 3 late last year, Google has shipped 3.5, 3.6, 3.7, 3.8 Flash variants along the way, the planned 3.5 Pro vanished without a trace (that&rsquo;s media reporting, Google never said), and Argon only comes out now. Anthropic&rsquo;s updates all landed on cheaper and faster. OpenAI&rsquo;s Sol is Astra&rsquo;s capability sold at a discount.</p>
<h2 id="so-does-the-old-guard-is-back-hold-up">So does &ldquo;the old guard is back&rdquo; hold up</h2>
<p>My read: rather than back, they changed how they play. Three things are pretty obvious.</p>
<p>One, they stopped competing on chat and started competing on whose work gets done. This month the keywords across all three are long-horizon software engineering, financial research, legal drafting, vulnerability repair, business workflows. All expensive, specialized, budgeted places.</p>
<p>Two, frontier models now ship in limited release. Google even says plainly this time that guardrails get hardened as access widens, and public release is &ldquo;gradual&rdquo;. That&rsquo;s not the era of publish a blog post and everyone can call it. Frontier capability looks more and more like a controlled resource.</p>
<p>Three, the price war changed its unit. It used to be dollars per million tokens. Now both sides quote cost per task. Sol&rsquo;s &ldquo;$5.47 per task versus $23.21&rdquo; is the most effective ad copy going right now.</p>
<p>So I&rsquo;m not comfortable with the word &ldquo;back&rdquo;. Nobody got chased out and returned. What happened is that once open source took cheap and self-hostable, this batch of old guard turned around to take expensive work and distribution.</p>
<p>For people writing AI clients, two parameters are worth actually remembering. One is cached input pushed down to $0.10 per million tokens, which is a direct cost variable for clients with long sessions and repeated context. The other is that the eval names changed: DeepSWE v1.1, AutomationBench, CWE-bench are closer to &ldquo;can you actually do the work&rdquo; than the MMLU generation was. Next time you pick a model, these beat the overall leaderboard.</p>
<h2 id="one-honest-boundary">One honest boundary</h2>
<p>There is no API key from any of them on this machine (I checked, all empty), so every number in this post — the 77.9%, the 51.3%, all the pricing — comes from official launch pages and public benchmark leaderboards. I have not run Argon, and can&rsquo;t. It is only open to trusted defenders in the Fairwind program.</p>
<p>What&rsquo;s official, what&rsquo;s media reporting, what&rsquo;s third-party prediction, I marked in the text. For example &ldquo;3.5 Pro was cancelled&rdquo; is media reporting. Polymarket odds are market prediction, not fact.</p>
<p>As for my own next step: the day it opens to paid API customers, I&rsquo;ll run it against the AI Chat client I have and watch two things — whether a one-million-token output cap is actually usable in a real conversation, and how much that $0.10 cached input saves over long sessions. Then I&rsquo;ll write one with data.</p>
<p>Do you think this round is &ldquo;the old guard is back&rdquo; or &ldquo;the old guard changed how it sells&rdquo;? When did you last genuinely pay for someone&rsquo;s API?</p>
<p>References:</p>
<ul>
<li>Introducing Gemini 4 Argon (Google official): <a href="https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-4-argon/">https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-4-argon/</a></li>
<li>Introducing GPT-6.1 Sol (OpenAI official): <a href="https://openai.com/index/introducing-gpt-6-1-sol/">https://openai.com/index/introducing-gpt-6-1-sol/</a></li>
<li>Anthropic Newsroom (Opus 5.5 / Sonnet 5.5 / Fable 5.1): <a href="https://www.anthropic.com/news">https://www.anthropic.com/news</a></li>
<li>Gemini API model list: <a href="https://ai.google.dev/gemini-api/docs/models">https://ai.google.dev/gemini-api/docs/models</a></li>
<li>Polymarket &ldquo;Gemini 4.0 released&rdquo; market: <a href="https://polymarket.com/zh/event/gemini-4pt0-released-by-june-30-2026">https://polymarket.com/zh/event/gemini-4pt0-released-by-june-30-2026</a></li>
</ul>
]]></content:encoded></item></channel></rss>