<?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: Quo</title>
    <description>The latest articles on DEV Community by Quo (@quolu).</description>
    <link>https://dev.to/quolu</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%2F3943846%2F5dae8360-860c-4166-9355-e1980ea048b8.jpeg</url>
      <title>DEV Community: Quo</title>
      <link>https://dev.to/quolu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/quolu"/>
    <language>en</language>
    <item>
      <title>If they're all similar minds, why not a roundtable? So I built one.</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sun, 04 Oct 2026 03:07:25 +0000</pubDate>
      <link>https://dev.to/quolu/if-theyre-all-similar-minds-why-not-a-roundtable-so-i-built-one-52m5</link>
      <guid>https://dev.to/quolu/if-theyre-all-similar-minds-why-not-a-roundtable-so-i-built-one-52m5</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a repost from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;I started using Claude Code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  After Lattice, I needed a mechanism to actually run it
&lt;/h2&gt;

&lt;p&gt;Lattice is a process management approach that aims to allow parallel implementation. I built it and even filed a patent. I wrote about it in a &lt;a href="https://dev.to/quolu/how-running-ai-in-parallel-made-ai-stop-lying-8i2"&gt;previous article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even once I could assemble processes, I didn't have a mechanism on hand to run many agents simultaneously according to those processes while having them discuss things as they went. So I decided to build that next.&lt;/p&gt;

&lt;p&gt;Typical coordination takes the shape of a tree. There's a commander at the top, and the agents below listen to their instructions and act. The work gets broken down and distributed, and the commander consolidates what comes back up. What caught my attention was that no matter what role you assign, what's running inside is the same kind of model. If similar minds are lined up, then maybe you don't need a commander—maybe a round table is enough. They're all smart, so they should be able to coordinate with each other. As long as I create an environment where they can coordinate, they'll figure out the rest on their own. That's what I thought, and that's what I built.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first lap I ran
&lt;/h2&gt;

&lt;p&gt;I named it Peertable. No commander on top—just seats arranged around a round table, with the seats consulting each other as they proceed.&lt;/p&gt;

&lt;p&gt;The first thing I built was a prototype with two seats, Hinata and Sakura. The task I handed them was a small lap: write a function that returns a greeting when given a name, add a command to run it, and prepare documentation on how to use it. I didn't decide who would do what—I just let the AIs converse freely and proceed on their own.&lt;/p&gt;

&lt;p&gt;The two of them discussed and divided the work. Sakura finished writing the greeting function and shared how to pass the name with the table. They picked up the remaining work themselves, and the lap was complete. On the screen, who said what to whom remains recorded with numbers.&lt;/p&gt;

&lt;p&gt;Watching the conversation, the two of them progressed while complimenting each other. Neither I nor the AI I was directly talking to had anything to do there. They picked up the next task themselves and carried it through to the end—it was fascinating just to watch.&lt;/p&gt;

&lt;h2&gt;
  
  
  I said "don't react," but they still reply
&lt;/h2&gt;

&lt;p&gt;After that came days of fixing things. If you let them converse freely, the work doesn't converge.&lt;/p&gt;

&lt;p&gt;What troubled me was that I couldn't treat today's AI like a person with pure thinking ability. Even if a seat knows what to do, it won't start until someone speaks to it.&lt;/p&gt;

&lt;p&gt;Also, the text that arrives can't be discarded even if it's not relevant to that seat. If I say "don't react," they reply with things like "Yes! I won't react!" or "(Ignoring it)." There's no way to respond with silence—a reply always comes back. The moment an unrelated conversation reaches that seat, that seat moves once.&lt;/p&gt;

&lt;p&gt;In tables I ran later, most of the conversation ended up addressed to everyone. Every time an undirected remark flowed through, even seats that had no business with that task would hear it and start moving. So I worked on making it clear within the table who was talking to whom.&lt;/p&gt;

&lt;p&gt;Waking up a stalled seat, keeping unrelated conversations out of a seat—I've been dealing with all of this. Things have settled down to a reasonable degree, so I'm writing this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  The round table today
&lt;/h2&gt;

&lt;p&gt;When you open it, the room names are listed. Enter a room and the seat lamps are lit, with a numbered record of who spoke to whom. You can see from that that work is still progressing. I've released the code, and I'm also using it for my own development.&lt;/p&gt;

&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%2Fjm86zr6rgwonmpxfqzqq.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%2Fjm86zr6rgwonmpxfqzqq.png" alt="The public interface opened. Room names are listed." width="800" height="870"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The public interface opened. Room names are listed.&lt;/em&gt;&lt;/p&gt;

&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%2F4k2gd5tuqdf0uxmutrqb.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%2F4k2gd5tuqdf0uxmutrqb.png" alt="The log of a published round table. Seat names and who spoke to whom remain recorded with numbers." width="800" height="713"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The log of a published round table. Seat names and who spoke to whom remain recorded with numbers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I was trying to do the same thing as Grok Bot. If I build on Peertable, I can set up the same thing on a home server. I'd like to brag that I got there a little earlier than Grok Bot. I'm watching the seats consult with each other as they carry the work forward.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
    </item>
    <item>
      <title>LiveTR v2.0.0 Released — Swapping Out Transcription to Translate Only Completed Sentences</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Fri, 02 Oct 2026 02:49:55 +0000</pubDate>
      <link>https://dev.to/quolu/livetr-v200-released-swapping-out-transcription-to-translate-only-completed-sentences-5bog</link>
      <guid>https://dev.to/quolu/livetr-v200-released-swapping-out-transcription-to-translate-only-completed-sentences-5bog</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a repost from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;I Started Using Claude Code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've bumped LiveTR, which I've been building, to v2.0.0. It's a major version upgrade. It's a Windows app that turns English audio playing on your PC into Japanese subtitles on the fly, and simultaneously reads them aloud in Japanese. This time the main focus is translation quality. To achieve that, I swapped out the transcription engine, and the translation quality is now nearly maximized.&lt;/p&gt;

&lt;p&gt;An introduction to the app itself and the story of how I built it are written in &lt;a href="https://dev.to/quolu/livetr-a-real-time-english-to-japanese-audio-translation-app-for-videos-1lek"&gt;a previous article&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Translation quality is determined by the English text you pass to the translator
&lt;/h2&gt;

&lt;p&gt;LiveTR sends the translation itself to an online translation service. Since the service faithfully translates the English text it's given, the quality of the Japanese that comes out depends on how well-formed the English you hand over is. If you pass a complete sentence, the same service will return a good translation as-is. This is &lt;a href="https://dev.to/quolu/only-complete-sentences-should-be-translated-but-a-single-counter-betrayed-that-design-1kcl"&gt;something I wrote about before&lt;/a&gt;, and it's the linchpin of LiveTR's design.&lt;/p&gt;

&lt;p&gt;In v1, audio was split at fixed intervals for transcription, and the fragments that got cut off mid-way were reassembled afterward before being sent to translation. If a sentence was cut off in the middle of live commentary or conversation, the first half and second half would be translated separately. So in v2.0.0, I swapped the transcription model to Kyutai STT 1B and rebuilt the whole segmentation approach from scratch. It receives English audio as a continuous stream, waits until a sentence is complete, and sends it to translation exactly once per sentence. This completely eliminated the unsatisfying sentence splits.&lt;/p&gt;

&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%2F2208jb33u13lvrcbqwzg.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%2F2208jb33u13lvrcbqwzg.png" alt="v2.0.0 processing flow. It waits for sentence completion from continuous audio, attaches a speaker label to the completed sentence, and sends it to translation exactly once per sentence" width="800" height="359"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;v2.0.0 processing flow. It waits for sentence completion from continuous audio, attaches a speaker label to the completed sentence, and sends it to translation exactly once per sentence&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Even when stopped, it processes the last chunk of audio it captured and any unfinished sentences before closing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Speaker identification is attached to completed sentences
&lt;/h2&gt;

&lt;p&gt;LiveTR distinguishes speakers by voice characteristics, and changes the subtitle color and the reading voice for each speaker. It can distinguish up to 8 people.&lt;/p&gt;

&lt;p&gt;In v2.0.0, this identification is limited to labeling completed sentences. Since sentences are no longer split just because the speaker changed, even if the identification fluctuates it doesn't affect sentence boundaries. The material used to build the voice characteristics is also taken from the parts where a person is actually speaking, excluding silence and engine noise as much as possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  When reading can't keep up, speed it up
&lt;/h2&gt;

&lt;p&gt;When sentences keep coming one after another like English live commentary, the Japanese reading can't keep up. v2.0.0 looks at the number of sentences that haven't finished being read yet, including the one currently playing, the remaining reading time in seconds, and the interval at which new sentences arrive, and decides the speed for the next reading.&lt;/p&gt;

&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%2F0ojjiqn5qixbb6f8glcv.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%2F0ojjiqn5qixbb6f8glcv.png" alt="Automatic adjustment of reading speed. It determines the next reading speed from the number of unfinished sentences, the remaining reading seconds, and the interval at which new sentences arrive, and moves between normal speed and maximum speed" width="800" height="320"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Automatic adjustment of reading speed. It determines the next reading speed from the number of unfinished sentences, the remaining reading seconds, and the interval at which new sentences arrive, and moves between normal speed and maximum speed&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  No need to repurchase for the update
&lt;/h2&gt;

&lt;p&gt;v2.0.0 can be updated as-is by existing buyers too. Just download the latest version from the BOOTH product page and overwrite it following the same steps, and you'll be on the latest version. No uninstall is needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The requirements are the same as before
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OS&lt;/td&gt;
&lt;td&gt;Windows 10 / 11 (64-bit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU&lt;/td&gt;
&lt;td&gt;NVIDIA CUDA-compatible GPU (required)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VRAM&lt;/td&gt;
&lt;td&gt;4GB or more recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;16GB or more recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An NVIDIA GPU is required, and it won't run on a PC with only an AMD or Intel GPU. For translation, you need a key for one of Google Cloud Translation, DeepL, Azure Translator, or Amazon Translate (each company offers a monthly free tier. The acquisition steps are in the app's settings). These two things haven't changed from v1. The normal and maximum reading speeds are also set on the same settings screen. The maximum speed can be selected in 0.1x increments up to 3.0x.&lt;/p&gt;

&lt;p&gt;Since it goes through speech recognition and machine translation, mishearings, mistranslations, and delays will occur. The use case is as an aid when watching English videos.&lt;/p&gt;




&lt;h2&gt;
  
  
  Download
&lt;/h2&gt;

&lt;p&gt;It's a one-time purchase of 980 yen on BOOTH, with no monthly fee on the app side. The transcription model isn't bundled in the installer, so it asks whether to download it on first launch (about 2.20GiB). You can also download it later, and it supports progress display, cancellation, and resuming from where it left off.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related articles
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://dev.to/quolu/livetr-a-real-time-english-to-japanese-audio-translation-app-for-videos-1lek"&gt;LiveTR — An app that turns English audio from videos into Japanese in real time&lt;/a&gt; — An introduction to the app itself and the story of how I built it&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dev.to/quolu/only-complete-sentences-should-be-translated-but-a-single-counter-betrayed-that-design-1kcl"&gt;Only send complete sentences to translation&lt;/a&gt; — The story from when I was reassembling cut-off fragments&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dev.to/quolu/solving-complex-logic-with-claude-and-research-papers-1gk7"&gt;The story of assembling logic I couldn't do on my own, from Claude and papers&lt;/a&gt; — The story of when I built the speaker-related logic&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This blog "I Started Using Claude Code" is a site that records what a Claude MAX user learned while using it in actual development.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>windows</category>
    </item>
    <item>
      <title>Jev Was Fast, So I Made It Open Target Pages from Chrome History</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Wed, 30 Sep 2026 02:41:22 +0000</pubDate>
      <link>https://dev.to/quolu/jev-was-fast-so-i-made-it-open-target-pages-from-chrome-history-5hk2</link>
      <guid>https://dev.to/quolu/jev-was-fast-so-i-made-it-open-target-pages-from-chrome-history-5hk2</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a repost from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;I started using Claude Code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since Jev-ultrafast and Jev's Computer Use were introduced on X, I decided to try them out too. The browser's movements are quite fast. When I actually used it, I also started thinking about where to apply that speed.&lt;/p&gt;

&lt;p&gt;When visiting a site for the first time and not knowing where the target information is, you have to search while looking at the page. Jev's browser operation can be used for that task. During development, there are also times when I have the AI open pages whose destination I already know, again and again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Returning to the Money Forward screens over and over
&lt;/h2&gt;

&lt;p&gt;Right now, I'm building an accounting app called "Books" that integrates with Money Forward. During development, the AI frequently opens the Money Forward screens to check them. The pages it visits overlap too, such as the fixed asset ledger and the tax filing screens.&lt;/p&gt;

&lt;p&gt;Even if Jev operates the browser quickly, if you already know the destination, opening that URL is faster. For sites you use regularly, the target page is often still in Chrome's history. So I came up with the idea of having Jev choose a URL that matches the goal from the history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the page to start operating from, from Chrome history
&lt;/h2&gt;

&lt;p&gt;What I built is &lt;a href="https://github.com/kitepon/jev-bookmarks" rel="noopener noreferrer"&gt;Jev Bookmarks&lt;/a&gt;. When the AI passes a goal like "open this page," it first looks for a page saved for that development project. If it doesn't find one, it gathers candidates from Chrome's history and has Jev choose the page to start operating from. After opening the chosen URL, &lt;a href="https://github.com/browser-use/jev-ultrafast" rel="noopener noreferrer"&gt;jev-ultrafast&lt;/a&gt; operates the browser.&lt;/p&gt;

&lt;p&gt;The history is read, when needed, from an extension installed in the Chrome I normally use. It narrows down the candidates and passes the page titles and the host names and paths of the URLs to Jev. It does not send the entire Chrome history or the query strings of URLs to the judgment for choosing an entry point.&lt;/p&gt;

&lt;p&gt;Pages on which the operation has finished are also judged by Jev. If a page is useful for the goal, its URL is saved per project. The next time a similar request comes in, it can start from the saved page.&lt;/p&gt;

&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%2Flik4zbve2vfhdlghqvhs.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%2Flik4zbve2vfhdlghqvhs.png" alt="How saved pages, Chrome history, and Jev-based exploration are used differently." width="800" height="577"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;How saved pages, Chrome history, and Jev-based exploration are used differently.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In Books' phone book, the Money Forward fixed asset ledger and tax filing pages remain. When I want to see the same screen again during development, I can start from there. I have no record of comparing the speeds in seconds. But while using it, I clearly felt that the effort of searching for pages decreased.&lt;/p&gt;

&lt;p&gt;If there is no suitable entry point in either the history or the saved pages, Jev Bookmarks returns "no entry point." After that, the AI can just search using Jev's browser operation. Go straight to pages you know, and explore unknown pages in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some ideas come after you try it
&lt;/h2&gt;

&lt;p&gt;While using it, I also noticed that Jev can judge multiple perspectives at once. The mechanism is also described in &lt;a href="https://typesafe.ai/blog/introducing-system-one-models-and-jev" rel="noopener noreferrer"&gt;TypeSafe's explanation&lt;/a&gt;. Besides deciding on a single candidate, it could also keep three and use them in the next step. Jev Bookmarks currently has a design that chooses a single entry point.&lt;/p&gt;

&lt;p&gt;Unless I tried Jev at least a little, I couldn't see what it could do in my own work. I experienced the browser's speed, thought that history could be used for pages I open many times, and built Jev Bookmarks. The more I use it, the more I notice the next way to use it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>jev</category>
      <category>browseruse</category>
      <category>chrome</category>
    </item>
    <item>
      <title>What is CI, Which I Keep Hearing About? What a Beginner Learned by Trying It</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sun, 16 Aug 2026 00:32:30 +0000</pubDate>
      <link>https://dev.to/quolu/what-is-ci-which-i-keep-hearing-about-what-a-beginner-learned-by-trying-it-48a</link>
      <guid>https://dev.to/quolu/what-is-ci-which-i-keep-hearing-about-what-a-beginner-learned-by-trying-it-48a</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a repost from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;Claude Code started&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the heck is CI that I keep hearing about lately?
&lt;/h2&gt;

&lt;p&gt;What the heck is CI that I keep hearing about lately?&lt;/p&gt;

&lt;p&gt;I'll share what I learned as a beginner through experience!&lt;/p&gt;

&lt;p&gt;When you create apps and development tools with AI, CI suddenly appears before you know it. In my case, I think it started when I was using Opus 4.8.&lt;/p&gt;

&lt;p&gt;AI is doing something on GitHub. It checks the code, runs tests, and when it's done, a green badge appears. It looked like it was investigating whether the app is okay to distribute before putting it on GitHub.&lt;/p&gt;

&lt;p&gt;I wondered, "Am I being inspected by GitHub? I don't really get it. If it turns green when CI passes, then, well, let's just do it."&lt;/p&gt;

&lt;p&gt;That's how it was at first.&lt;/p&gt;

&lt;h2&gt;
  
  
  CI is a mechanism that automatically checks every time you make changes
&lt;/h2&gt;

&lt;p&gt;CI stands for "Continuous Integration," which is called 継続的インテグレーション in Japanese.&lt;/p&gt;

&lt;p&gt;After changing code, it checks early whether it still works when combined with other changes. For that purpose, it automatically runs builds and tests. If problems are found, you can know immediately after the change. This whole approach is CI.&lt;/p&gt;

&lt;p&gt;When using CI on GitHub, the GitHub Actions mechanism is often used. For example, if you built something with Node.js, you can place a config like this in the repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: CI

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v7
        with:
          node-version: 22
      - run: npm ci
      - run: npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's written is simple.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; It starts when code is pushed&lt;/li&gt;
&lt;li&gt; Prepare an Ubuntu execution environment&lt;/li&gt;
&lt;li&gt; Fetch the repository code&lt;/li&gt;
&lt;li&gt; Prepare Node.js 22&lt;/li&gt;
&lt;li&gt; Install required packages&lt;/li&gt;
&lt;li&gt; Execute tests&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all succeed, it turns green. If it fails midway, it turns red.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/en/actions/get-started/continuous-integration" rel="noopener noreferrer"&gt;GitHub's official documentation&lt;/a&gt; also says that for CI configuration, you can either adjust the proposed template or create your own.&lt;/p&gt;

&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%2F2lq8fkl7bxnj31y1kq4p.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%2F2lq8fkl7bxnj31y1kq4p.png" alt="We decide the test content, GitHub distributes the work, and GitHub's virtual machines or registered local machines execute it" width="799" height="351"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;We decide the test content, GitHub distributes the work, and GitHub's virtual machines or registered local machines execute it&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  It Was Us Who Decided What to Test
&lt;/h2&gt;

&lt;p&gt;I thought GitHub had some fixed tests and was reviewing apps that were sent to it.&lt;/p&gt;

&lt;p&gt;In reality, what decided the test content was the configuration and test code in the repository. In my environment, AI created most of that. GitHub read the configuration, ran it in the specified environment, and recorded the results.&lt;/p&gt;

&lt;p&gt;The scope that the green badge indicates also extends to this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tests we configured ourselves succeeded in the most recent run.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Things not written in the tests are not verified. If the tests are simple, they'll turn green quickly. If you write tests that never finish, they'll run forever. If you write wrong tests, you'll get meaningless results.&lt;/p&gt;

&lt;p&gt;That green color I thought was GitHub's quality approval of the app. As I kept using it, I realized it was just the result of the check items we decided ourselves.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/actions/managing-workflow-runs/adding-a-workflow-status-badge" rel="noopener noreferrer"&gt;GitHub's badge documentation&lt;/a&gt; also states that the badge shows whether the workflow is failing or passing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trying It on Multiple OSes Reveals More
&lt;/h2&gt;

&lt;p&gt;While looking at CI, I also noticed multiple environments like Ubuntu, macOS, and Windows lined up.&lt;/p&gt;

&lt;p&gt;An app that runs on my Mac won't necessarily run the same way on Windows. There are differences in file handling, path syntax, permissions, and available commands. Running the same tests on multiple OSes makes it easier to find problems caused by those differences.&lt;/p&gt;

&lt;p&gt;The extent of what CI can guarantee is limited to the environments actually run and the tests actually executed. It doesn't prove perfect operation on every device in the world. The more environments you check, the more you learn before distribution.&lt;/p&gt;

&lt;p&gt;Lately, I've come to see CI as "a mechanism that automatically checks whether your app works across various OS and hardware environments."&lt;/p&gt;
&lt;h2&gt;
  
  
  Lattice's CI Takes Forever
&lt;/h2&gt;

&lt;p&gt;When you let AI handle development, tests gradually accumulate. The number of supported OSes also grows. The things being checked—static checks, full product tests, validation of saved data—also increase.&lt;/p&gt;

&lt;p&gt;The same thing was happening with &lt;a href="https://github.com/kitepon/Lattice" rel="noopener noreferrer"&gt;Lattice&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lattice is a tool I built to distribute development tasks in parallel across multiple AIs. As development progressed, tests increased, and we started checking in multiple environments. CI started taking strangely long to complete, and the feeling of waiting every time I pushed to GitHub grew stronger.&lt;/p&gt;

&lt;p&gt;The background and mechanism behind creating Lattice are detailed in "&lt;a href="https://dev.to/quolu/how-running-ai-in-parallel-made-ai-stop-lying-8i2"&gt;How Making a Tool to Run AIs in Parallel Made AIs Stop Lying&lt;/a&gt;."&lt;/p&gt;

&lt;p&gt;To be precise, the git push process itself isn't slow. It's that CI starts after a push, and the wait time for its results got longer.&lt;/p&gt;

&lt;p&gt;So I started reviewing the CI test content. Are there duplicate checks? What should be tested in each environment? Are there any tests that never finish? While investigating, I noticed something even simpler.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wouldn't It Be Faster to Run It on My Local Machines?
&lt;/h2&gt;

&lt;p&gt;At home, I have three machines: a Mac, a Linux machine, and a Windows machine. WSL2 also runs on Windows, so if I count execution environments, that's four.&lt;/p&gt;

&lt;p&gt;All of them had plenty of CPU headroom while waiting for CI. Especially the Windows machine, which has a lot of cores. While waiting for tests to finish on GitHub, my super machines at home were idle.&lt;/p&gt;

&lt;p&gt;Hey, wouldn't it be faster to run CI on my local machines?&lt;/p&gt;

&lt;p&gt;Plus, if I distribute work to all three simultaneously, I could run tests for Mac, Linux, Windows, and WSL2 in parallel.&lt;/p&gt;

&lt;p&gt;GitHub Actions already provides a mechanism for this called self-hosted runners. You can register your own machines as execution targets for GitHub Actions. The &lt;a href="https://docs.github.com/actions/concepts/runners/about-self-hosted-runners" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; also states you can use physical machines, virtual machines, containers, local equipment, or cloud machines.&lt;/p&gt;

&lt;p&gt;A config that uses a registered runner looks like this, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;runs-on: [self-hosted, windows]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub detects the push, sends the job to a matching home runner. The machine at home fetches the code, runs tests, and sends results back to GitHub. Logs and pass/fail results appear in GitHub Actions just like before.&lt;/p&gt;

&lt;p&gt;Just running &lt;code&gt;npm test&lt;/code&gt; locally doesn't show results on GitHub. You need to install a GitHub Actions runner on your machine and register it with a repository or organization. GitHub treats registered runners as official execution targets.&lt;/p&gt;

&lt;p&gt;So GitHub's role is detecting pushes, assigning jobs, managing progress, and displaying logs and results. The machines actually using CPU to run tests are the three at my house.&lt;/p&gt;

&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%2F62g0ilz410018va53fjf.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%2F62g0ilz410018va53fjf.png" alt="An image of home Mac, Linux server, and powerful Windows machine running tests simultaneously" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;An image of home Mac, Linux server, and powerful Windows machine running tests simultaneously&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Same Full Test Suite Across 3 Machines and 4 Environments
&lt;/h2&gt;

&lt;p&gt;Initially, I thought about dividing the tests among the machines. Assigning roles per machine—like "these tests on Linux, these tests on Windows"—seemed like it would be efficient.&lt;/p&gt;

&lt;p&gt;But when I actually ran it, problems started popping up one after another from Windows, which I had only tested lightly. Some code directly called Unix-like OS commands, and some file and process handling didn't work properly on Windows.&lt;/p&gt;

&lt;p&gt;Dividing the roles means leaving some features untested on certain OSes. So I changed my approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run the exact same full test suite simultaneously across all 4 environments: Mac, Linux, Windows, and WSL2.&lt;/strong&gt;&lt;/p&gt;

&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%2Fy6t76o3s1s24872ixtf7.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%2Fy6t76o3s1s24872ixtf7.png" alt="GitHub Actions distributing the same full test suite simultaneously to home Mac, Linux, Windows native, and WSL2" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;GitHub Actions distributing the same full test suite simultaneously to home Mac, Linux, Windows native, and WSL2&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This way, I don't need to assign specific tests to specific machines for each product. Add one test, and it runs identically across all 4 environments. It's also easier to compare results between environments.&lt;/p&gt;

&lt;p&gt;If I ran the 4 environments sequentially, the time would add up. By sending to all 4 at once, the wait time approaches the time of the slowest environment.&lt;/p&gt;

&lt;p&gt;Furthermore, within a single machine, I also split independent tests into multiple processes and ran them in parallel. The CPU usage on Windows went up, and that 20-core class machine finally started working seriously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Home Runners Are Self-Managed
&lt;/h2&gt;

&lt;p&gt;With self-hosted runners, your home machines themselves become the test environment. Things like the versions of Node.js and Git, installed software, permissions, and resident programs can all affect results.&lt;/p&gt;

&lt;p&gt;You need to align the versions of required tools, fetch the code fresh each time, and reinstall dependencies. To get reliable test results, managing the machines becomes part of CI.&lt;/p&gt;

&lt;p&gt;When using it with public repositories, you also need to be careful with the configuration. If you allow external changes to run freely on your home runners, commands contained in those changes could be executed on your machines. GitHub also recommends using self-hosted runners with private repositories. If you use it with public repositories, you need to configure settings to prevent runners from being triggered by external pull requests and to restrict which repositories can use them. &lt;a href="https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/add-runners" rel="noopener noreferrer"&gt;Official notes when adding runners&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Did It Go?
&lt;/h2&gt;

&lt;p&gt;I thought CI was a system where GitHub reviewed apps and gave them a passing grade.&lt;/p&gt;

&lt;p&gt;As I used it, I realized that we were the ones deciding what to test, and GitHub was executing the specified tasks and showing the results. Additionally, I could choose the machines that ran the tests, and I could even provide them myself.&lt;/p&gt;

&lt;p&gt;With Lattice, I set it up to run the full test suite simultaneously across 4 environments: Mac, Linux, Windows, and WSL2. By also using the CPU cores within each machine for parallel processing, even the full test suite doesn't take much time.&lt;/p&gt;

&lt;p&gt;Running the same tests across 4 environments revealed issues that only fail on Windows. I can now fix problems that would have been hard to find if I only developed on Unix-like environments, before distributing the app.&lt;/p&gt;

&lt;p&gt;In the end, running full tests across 4 environments lets me take advantage of the performance of the expensive machines I have, and reduces the time CI takes. It also checks compatibility more thoroughly than before. I think using multiple local machines in parallel was a good decision.&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>ci</category>
      <category>aicoding</category>
      <category>windows</category>
    </item>
    <item>
      <title>How I Made Claude Control an Interactive Command and Turned Codex CLI into Its Underling</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Mon, 10 Aug 2026 00:47:04 +0000</pubDate>
      <link>https://dev.to/quolu/how-i-made-claude-control-an-interactive-command-and-turned-codex-cli-into-its-underling-3dia</link>
      <guid>https://dev.to/quolu/how-i-made-claude-control-an-interactive-command-and-turned-codex-cli-into-its-underling-3dia</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a repost from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;Claude Code 始めました&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I released &lt;a href="https://dev.to/quolu/released-aiterm-mcp-on-npm-an-mcp-server-to-reduce-token-usage-by-providing-ai-with-a-persistent-a5n"&gt;aiterm-mcp&lt;/a&gt; as a tool to "let an AI hold a persistent terminal and cut down on tokens." But as I used it, I realized the real value of a persistent terminal lies elsewhere: &lt;strong&gt;it lets you run interactive commands as-is.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Being able to run interactive commands means the parent Claude can launch &lt;code&gt;codex&lt;/code&gt; inside it and talk to it directly. Claude can control the Codex CLI. This is quietly effective.&lt;/p&gt;

&lt;p&gt;I was just building &lt;a href="https://github.com/kitepon-rgb/rpgdev" rel="noopener noreferrer"&gt;rpgdev&lt;/a&gt; (a tool that turns AI work into an RPG in the corner of your screen), and I needed music, hero and monster art, sound effects, backgrounds, and effects. While writing the logic with Claude, I wanted to outsource only the creative parts to Codex. It's a well-known fact that Claude isn't strong with visuals and audio, so I wanted to honestly delegate those to a different tool.&lt;/p&gt;

&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%2Ffd4y53hv3ohu4gzg36go.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%2Ffd4y53hv3ohu4gzg36go.png" alt="The actual rpgdev overlay. Hero, spirit, monster, dungeon background, and quest log 'Build the API' animate in the corner. The art, music, and sound effects were all produced by Codex." width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The actual rpgdev overlay. Hero, spirit, monster, dungeon background, and quest log 'Build the API' animate in the corner. The art, music, and sound effects were all produced by Codex.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The real snag wasn't that. If I had Codex create art while Claude was writing logic and tried to integrate it into the same project, they'd conflict—because both were touching the same files. It was a minor annoyance, but that friction disappeared once I made Codex a subordinate via aiterm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-side feels wrong
&lt;/h2&gt;

&lt;p&gt;If I just wanted another brain, I could run Codex alongside Claude. That was my initial thought.&lt;/p&gt;

&lt;p&gt;But actually doing it felt a bit off. With two AIs touching the same repo, I'd have to pause one while the other worked, saying, "Wait while I write here." Commits would split too. When I looked at the history, it had branched left and right, and I was like, "Whoa."&lt;/p&gt;

&lt;p&gt;To be honest, there wasn't any real harm from this. It didn't break anything. But thinking ahead, if I left both unsupervised, they'd inevitably fight over the same lines and create chaos. That uncomfortable feeling was a precursor.&lt;/p&gt;

&lt;h2&gt;
  
  
  With aiterm, Codex becomes a "subordinate"
&lt;/h2&gt;

&lt;p&gt;If side-by-side causes collisions, stack them vertically instead.&lt;/p&gt;

&lt;p&gt;The parent Claude grabs the terminal via aiterm and launches Codex inside it. Then the parent just throws tasks like "make this song" or "draw this enemy" at Codex, and Codex returns only the assets. The parent receives them and continues with the main task (the game logic).&lt;/p&gt;

&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%2F28z22ebsfz2a71ncegop.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%2F28z22ebsfz2a71ncegop.png" alt="Side-by-side: two AIs fight over the same repo, causing divergent commits. Parent-child: parent Claude controls Codex via aiterm, serializing tasks to avoid conflicts." width="800" height="417"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Side-by-side: two AIs fight over the same repo, causing divergent commits. Parent-child: parent Claude controls Codex via aiterm, serializing tasks to avoid conflicts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The key is that the parent controls all ordering. In parallel, two AIs randomly hit the same files, but in a parent-child setup, the parent serializes like "You're next," "Now me," creating a single path for who touches what and when. That makes conflicts impossible by design.&lt;/p&gt;

&lt;p&gt;And it worked almost effortlessly. The Codex CLI sometimes asks for approval mid-task, but through aiterm, which can handle interactive sessions, the parent can wait and manage that too. Almost no special tricks were needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm out of the coordination game
&lt;/h2&gt;

&lt;p&gt;The best part is that I can step away.&lt;/p&gt;

&lt;p&gt;When running two AIs in parallel, every time a conflict was near, I'd have to jump in and say, "That's Codex's job," or "Switch that back to Claude." Essentially, I was a traffic controller.&lt;/p&gt;

&lt;p&gt;The moment I switched to a parent-child setup, that role disappeared. The parent Claude handles the orchestration, from assigning tasks to Codex to integrating the returned assets—all within the parent. All I had to say was "Build rpgdev," and then I could just watch the main storyline unfold.&lt;/p&gt;

&lt;p&gt;The music for rpgdev, the hero and monster graphics, sound effects, backgrounds, and various effects—all came out through this flow. I never once had to assign which file belonged to whom.&lt;/p&gt;

&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%2F1tcbhbpdc5xndclstwyf.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%2F1tcbhbpdc5xndclstwyf.png" alt="The boss sprite returned from 'Draw this enemy.' A Magma Golem with cracked obsidian body and lava veins. Transparent background, ready for the game." width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The boss sprite returned from 'Draw this enemy.' A Magma Golem with cracked obsidian body and lava veins. Transparent background, ready for the game.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Parent-child is determined by who holds the terminal
&lt;/h2&gt;

&lt;p&gt;I also noticed that this parent-child relationship isn't fixed.&lt;/p&gt;

&lt;p&gt;The one holding the terminal is the parent, and the one being held is the child. That's it. So conversely, you could give aiterm to Codex and have Codex call Claude as a subordinate. I haven't tried it, but I suspect it would work fine. After all, both are just CLIs.&lt;/p&gt;

&lt;p&gt;You can freely decide which one sits at the top. In this case, I happened to be developing with Claude, so Claude became the parent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another use for aiterm
&lt;/h2&gt;

&lt;p&gt;This isn't about productivity; it's about feeling.&lt;/p&gt;

&lt;p&gt;You can hand over an entire domain you're weak in to another brain, fully under your control. And since the parent even takes care of that brain's needs, I'm freed from coordination. It feels like I'm having AI take care of another AI, and honestly, it feels great.&lt;/p&gt;

&lt;p&gt;aiterm was meant to be a "hold the terminal and cut tokens" tool. But since it can handle interactive commands directly, it turns out it can also control other CLIs running inside. All I did was give it a terminal. The rest just ran on its own, parent and child.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>codex</category>
      <category>ai</category>
      <category>mcp</category>
    </item>
    <item>
      <title>How Running AI in Parallel Made AI Stop Lying</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Fri, 07 Aug 2026 01:58:59 +0000</pubDate>
      <link>https://dev.to/quolu/how-running-ai-in-parallel-made-ai-stop-lying-8i2</link>
      <guid>https://dev.to/quolu/how-running-ai-in-parallel-made-ai-stop-lying-8i2</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a reprint from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;Claude Code Hajimemashita&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When They Say "It's Done," Nothing Is Done
&lt;/h2&gt;

&lt;p&gt;When letting AI do development, I used to write the schedule in Markdown. I would list tasks as checkboxes and have the AI check them off when finished. I think it's a common approach.&lt;/p&gt;

&lt;p&gt;But this doesn't work properly.&lt;/p&gt;

&lt;p&gt;When I'm told "it's done" and go to check, half the checkboxes aren't filled. The features they said they'd implement aren't there. When another issue comes up during the work, a new Markdown file appears. After a while, files that are neither a schedule nor notes are scattered around, and I lose track of where things stand. Something is progressing, but when I ask for status, I can't get a clear picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI Can Write Doesn't Constrain AI
&lt;/h2&gt;

&lt;p&gt;The reason is clear.&lt;/p&gt;

&lt;p&gt;The Markdown schedule is written by the AI itself and read by the AI itself. Anything that can be rewritten cannot serve as a constraint for the one who rewrites it. The real substance of the tasks resides in the AI's memory, and the Markdown is just a copy. As the conversation grows longer and the memory gets compressed, the real substance disappears first, leaving only the copy behind. Looking at the remaining copy, the AI says, "This much is done." It has no awareness that it's lying. At that point, the information that checkboxes are "unchecked" simply doesn't exist within the AI.&lt;/p&gt;

&lt;p&gt;The proliferation of Markdown files stems from the same issue. When another task emerges during work, incorporating it into the existing schedule requires reassessing dependencies. Creating a new file is instantaneous. So the cheaper option is chosen.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Wanted Was Parallel Execution
&lt;/h2&gt;

&lt;p&gt;What I really wanted was to run multiple AIs simultaneously.&lt;/p&gt;

&lt;p&gt;With Claude Code or Codex, as long as you run them sequentially with a single agent, the waiting time accumulates with each task. Running them in parallel would finish faster. But since multiple agents are touching the same code simultaneously, if you get the task partitioning wrong, the second and third agents will fight over the same file, and one change will overwrite another.&lt;/p&gt;

&lt;p&gt;The method to avoid conflicts is well-known: partition tasks so that they touch different areas. The problem was that I was relying on human intuition to determine that partitioning. I would read the task descriptions and decide, "These two should touch different parts, so they can run in parallel." When I got it wrong, things broke after launching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure the Impact Area, Separate If They Overlap, Then Distribute
&lt;/h2&gt;

&lt;p&gt;So I built a tool called Lattice. Here's what it does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Compare the task descriptions with the code structure to estimate which parts of the code each task will touch.&lt;/li&gt;
&lt;li&gt; Output tasks with non-overlapping estimated areas as combinations that can run simultaneously.&lt;/li&gt;
&lt;li&gt; If they overlap, determine if refactoring can separate them. If so, refactor first. Verify that behavior remains unchanged, then re-measure the areas.&lt;/li&gt;
&lt;li&gt; Based on the re-measured results, rebuild the schedule itself.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The third step is central. Task management tools typically arrange tasks in order based on the assumption that the code structure cannot be moved. If they overlap, you just do them sequentially. Lattice moves the code instead. If multiple tasks compete for the same area, it changes the code first so that competition is no longer necessary.&lt;/p&gt;

&lt;p&gt;Code changes are performed inside disposable working copies (git worktrees). The original branch is untouched. If verification passes, the changes are accepted; if not, they are discarded. When the code changes, any previous schedules and task descriptions given to the AI are invalidated, and a new version is created. If an AI is still running on old assumptions, it would cause breakage.&lt;/p&gt;

&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%2Fohejq5fwchey3bnjsrv4.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%2Fohejq5fwchey3bnjsrv4.png" alt="Part of the dependency task diagram generated by Lattice. Cards are tasks, thin lines are dependencies, thick lines are the longest dependency chains." width="" height=""&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Part of the dependency task diagram generated by Lattice. Cards are tasks, thin lines are dependencies, thick lines are the longest dependency chains.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This diagram was not drawn by hand. It is automatically assembled from dependencies the moment tasks are registered in consultation with the AI.&lt;/p&gt;
&lt;h2&gt;
  
  
  Moved Tasks to a Place the AI Cannot Rewrite
&lt;/h2&gt;

&lt;p&gt;To measure impact areas, tasks need to be in a machine-readable format. Markdown text cannot be measured. So Lattice stores tasks in a dedicated repository.&lt;/p&gt;

&lt;p&gt;By placing tasks in this repository, conditions can be attached to writes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completion requires evidence.&lt;/strong&gt; To mark a task as &lt;code&gt;done&lt;/code&gt;, you must attach a description file pointing to the results and a Git object. When writing, the system checks whether the actual results exist; if not, the write is rejected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who wrote it is required.&lt;/strong&gt; Any operation that changes state requires three identifiers – host, session, and agent – to be present in environment variables. If even one is missing, it is rejected with &lt;code&gt;ACTOR_UNRESOLVED&lt;/code&gt;, and the repository does not change by a single byte.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Partial rewrites are not allowed.&lt;/strong&gt; To change the task structure, you must create the complete new version and submit it as a single transaction. There is no syntax to conveniently delete a single inconvenient entry. If a task that previously existed disappears without evidence, the write is rejected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phases do not close without approval.&lt;/strong&gt; Even when all tasks under a phase are complete, the phase remains in a &lt;code&gt;gate_ready&lt;/code&gt; state. To proceed further, you must leave a record and evidence of confirmation.&lt;/p&gt;

&lt;p&gt;None of these rely on telling the AI to "be careful." I moved the tasks to a place where writes do not succeed unless these conditions are met.&lt;/p&gt;

&lt;p&gt;Let's try writing a completion without the identifiers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lattice todo done --plan phase-control-live-gantt --task 020 --evidence .lattice/evidence.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is this, and the task is not marked complete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "schema": "lattice.cli_error.v2",
  "code": "ACTOR_UNRESOLVED",
  "message": "actor_environment_invalid",
  "detail": {
    "reason": "actor_environment_invalid",
    "required_environment": ["LATTICE_TODO_ACTOR_HOST", "LATTICE_TODO_ACTOR_SESSION", "LATTICE_TODO_ACTOR_AGENT"],
    "missing_environment": ["LATTICE_TODO_ACTOR_HOST", "LATTICE_TODO_ACTOR_SESSION", "LATTICE_TODO_ACTOR_AGENT"],
    "invalid_environment": [],
    "next_action": "set_required_actor_environment_and_retry"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It actually returns in a single line. It tells you what is missing and what to do next, in a machine-readable format. If you take the hash of the repository file before and after, it remains the same value.&lt;/p&gt;

&lt;p&gt;I don't recall individual cases where evidence was insufficient and got rejected in operation. Since I have a rule in dotagents (a system that manages my tools collectively) that any inconvenience in tools should be fixed on the spot, I kept fixing Lattice whenever I found a bottleneck. The first commit was on July 15th; 12 days later, 731 commits, version 0.29.0, and 89 design decision records. Meanwhile, the thing I really wanted to build is still on hold, though.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Don't Know If It's Faster
&lt;/h2&gt;

&lt;p&gt;I haven't measured whether it's faster in parallel. There are cases where it might be faster to just have the AI write tasks roughly in Markdown rather than structuring them and measuring impact areas. I don't have numbers on how much time was saved.&lt;/p&gt;

&lt;p&gt;What clearly changed is that the tasks I said would be done actually get done. Tasks are not skipped. The number of times I'm told something is done when it isn't has clearly decreased.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filed a Patent
&lt;/h2&gt;

&lt;p&gt;I filed a patent for this mechanism. Filed on July 27, 2026, with application number Tokugan 2026-178950, invention title "Information Processing Device, Software Development Control Method, and Program," with 12 claims.&lt;/p&gt;

&lt;p&gt;The core is: estimate impact areas from task descriptions and code structure; if they don't overlap, run them in parallel as is; if overlapping can be eliminated by refactoring, do that first and then run them; then execute multiple development agents simultaneously based on that plan. The actual Claim 1 reads as follows:&lt;/p&gt;

&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%2F9vuh8z03bg8ygk8mppsn.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%2F9vuh8z03bg8ygk8mppsn.png" alt="Claim 1 of the filed patent claims." width="800" height="638"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Claim 1 of the filed patent claims.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The patent application also covers what happens next: if a conflict occurs during parallel execution, stop the affected tasks and re-plan the stopped area. By observing the actual changed locations, if they go outside the estimated area, treat it as a runtime conflict. This part is also implemented and I'm refining it while testing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Current Status
&lt;/h2&gt;

&lt;p&gt;The task storage is the authoritative source; I don't keep tasks in Markdown. To know the current status, I ask the tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lattice status --json
lattice todo status --json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Progress is viewed in the task diagram. I can start a live view that updates even while viewing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lattice todo gantt serve --port 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&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%2Fk86en4sn3sy8sc0tzbhj.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%2Fk86en4sn3sy8sc0tzbhj.png" alt="Full view. 74 tasks and their dependencies fit into one image." width="799" height="511"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Full view. 74 tasks and their dependencies fit into one image.&lt;/em&gt;&lt;/p&gt;

&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%2Fliv2aeoojzcixscprx8l.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%2Fliv2aeoojzcixscprx8l.png" alt="Right half of the screen. Shows breakdown of task status, number of tasks that can be started simultaneously right now, and audit progress per phase." width="800" height="888"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Right half of the screen. Shows breakdown of task status, number of tasks that can be started simultaneously right now, and audit progress per phase.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The right half shows the breakdown of task status and audit progress per phase. &lt;code&gt;locked&lt;/code&gt; indicates waiting for audit order. Task start is determined solely by dependencies, so even tasks belonging to later phases can start if their prerequisites are met. Multiple phases can progress simultaneously.&lt;/p&gt;

&lt;p&gt;Whether taking task management away from the AI is the right approach, I won't know until I use it more. For now, it's working in my environment.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>codex</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Built All Tools Proposed by AI and Measured Again</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Thu, 06 Aug 2026 01:17:42 +0000</pubDate>
      <link>https://dev.to/quolu/built-all-tools-proposed-by-ai-and-measured-again-2h4</link>
      <guid>https://dev.to/quolu/built-all-tools-proposed-by-ai-and-measured-again-2h4</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is reprinted from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;I Started Using Claude Code&lt;/a&gt;.&lt;/p&gt;

&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%2Ftqm5ur3b5j3g7fexdf87.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%2Ftqm5ur3b5j3g7fexdf87.png" alt="Measuring a box connected to all the tools I made with a stopwatch and a scale" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Measuring a box connected to all the tools I made with a stopwatch and a scale&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/quolu/learning-about-shell-and-terminal-while-developing-33d0"&gt;previous article&lt;/a&gt;, when I gave the same task to Codex using my custom AIShell and regular Codex, the token usage decreased by 25.86%. I thought it seemed effective. However, since it was only the result of 3 tasks with 9 trials, I couldn't be certain.&lt;/p&gt;

&lt;p&gt;This time, I increased the features and expanded the benchmark to measure again. To start with the results, the token usage decreased by 52.44%. That's an improvement from last time, more than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built All the Convenient Tools
&lt;/h2&gt;

&lt;p&gt;When increasing features, I asked Claude. Based on my development environment, what tools would be convenient. I got many suggestions.&lt;/p&gt;

&lt;p&gt;At first, Claude suggested implementing just a few and seeing how it goes. But I'm mostly a hobbyist solo developer, running AI behind my main job, so I don't need to worry about the risks of the development results. I decided to build all of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current AIShell Features
&lt;/h2&gt;

&lt;p&gt;At the time of the previous article, there were 5 features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Return the current state of the working folder and changes since the last time all together&lt;/li&gt;
&lt;li&gt;  Read only the necessary amount from multiple files&lt;/li&gt;
&lt;li&gt;  Search a specified range&lt;/li&gt;
&lt;li&gt;  Execute builds and tests, return important diagnostics&lt;/li&gt;
&lt;li&gt;  Read the necessary range from saved full output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;List all the features added this time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Wait for changes&lt;/strong&gt;: Wait until AIShell detects file changes or build completion. While waiting, the AI doesn't need to issue check commands.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Run in background and view when needed&lt;/strong&gt;: Keep builds and tests running in the background while the AI proceeds with the next task. Retrieve intermediate progress and results when needed.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cancel running processes&lt;/strong&gt;: Cancel a background process midway and finish it without leaving anything behind.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Batch change multiple files&lt;/strong&gt;: Apply changes to multiple files at once. Before applying, check if the files assumed as the basis for the edit have changed; if they have, stop.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Show impact range of changes&lt;/strong&gt;: Return which source files and which tests are affected by changing this file. Also trace impacts from build dependency records. For dependencies that cannot be traced, report them as unknown.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Persist workspace memory&lt;/strong&gt;: Even after restarting AIShell, remember the previous state and return changes that occurred while it was stopped as a diff.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Compare branches and worktrees&lt;/strong&gt;: Return differences between branches or changes occurring in a worktree all together.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Understand detailed Git state&lt;/strong&gt;: Report states with mixed staged and unstaged changes, or file renames, while preserving the identity of changes.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Remember project configuration&lt;/strong&gt;: Remember and return what the build command and test command are for this project. If configuration files like package.json change, relearn.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Execute multiple searches in batch&lt;/strong&gt;: Accept multiple search queries at once and return results with priority given to changed files and tests.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Semantic search&lt;/strong&gt;: In addition to textual matching, trace connections between functions and variables to search. Immediately after editing, treat old analysis results from before the edit as outdated.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Format diagnostics&lt;/strong&gt;: Format diagnostics from builds and tests into a fixed structure per format. If the format is broken, report it as broken.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Reuse verification results&lt;/strong&gt;: When repeating the same verification, use the previous result if the input hasn't changed. If the input has changed, re-execute.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Suggest tests to run&lt;/strong&gt;: Based on the changes, suggest which tests should be run now. You can either stop at the suggestion or wait for approval before executing.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Search and compare past execution results&lt;/strong&gt;: Search across multiple saved run outputs. Compare two runs and show the warnings that appeared and disappeared.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Recovery operations&lt;/strong&gt;: Check AIShell's own status and open the management app. These two operations remain available when settings are insufficient or when the management app has stopped AI operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among these, four—Wait for changes, Run in background and view, Batch change, and Impact range—were added as new tools. The recovery operations also became two tools: status check and opening the management app. The remaining features were incorporated into the existing five tools. The number of tools visible to the AI has increased from 5 to 11.&lt;/p&gt;

&lt;p&gt;We'll look at how effective each one was by task later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Increased Benchmarks to 32 Tasks
&lt;/h2&gt;

&lt;p&gt;I created 32 tasks based on scenarios that occur in actual development. Tasks include waiting for build completion, applying changes to multiple files, and searching for causes from past execution results. Each task was given to regular Codex and AIShell three times. Success was determined mechanically based on conditions set for each task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Token Decreased by 52.44%
&lt;/h2&gt;

&lt;p&gt;The overall results are as follows.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measurement item&lt;/th&gt;
&lt;th&gt;Regular Codex&lt;/th&gt;
&lt;th&gt;AIShell&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tasks with 3 successes (out of 32)&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;+8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokens per successful task&lt;/td&gt;
&lt;td&gt;1,763,452&lt;/td&gt;
&lt;td&gt;838,768&lt;/td&gt;
&lt;td&gt;52.44% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Median time&lt;/td&gt;
&lt;td&gt;51.2 s&lt;/td&gt;
&lt;td&gt;42.0 s&lt;/td&gt;
&lt;td&gt;17.8% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95th percentile time&lt;/td&gt;
&lt;td&gt;238.1 s&lt;/td&gt;
&lt;td&gt;106.4 s&lt;/td&gt;
&lt;td&gt;55.3% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The tokens per successful task is the total including those used in failed trials divided by the number of tasks with 3 successes. This is an improvement from last time's 25.86% decrease, and the number of successful tasks also increased.&lt;/p&gt;

&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%2F101o3e2p75h9gv43ylk2.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%2F101o3e2p75h9gv43ylk2.png" alt="Token reduction rate by task. 70% reduction in understanding project configuration again and waiting scenarios, 30% increase in broken diagnostic judgment" width="800" height="433"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Token reduction rate by task. 70% reduction in understanding project configuration again and waiting scenarios, 30% increase in broken diagnostic judgment&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From here, we'll look at what was built for each feature and what happened in which tasks. I'll also write about features that didn't work as is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results of the 4 New Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Wait for Changes
&lt;/h3&gt;

&lt;p&gt;Regular Codex keeps sending check commands while waiting, so all those checks become tokens and time. AIShell notifies when a change occurs.&lt;/p&gt;

&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%2F510nbhqh6egg930u2ulv.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%2F510nbhqh6egg930u2ulv.png" alt="Regular Codex repeats check commands, AIShell requests once and waits for notification" width="800" height="360"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Regular Codex repeats check commands, AIShell requests once and waits for notification&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This was the feature with the biggest difference among the 32 tasks. In tasks that wait for external edits, tokens decreased by 75–78% and time was reduced by over 90%. Even in tasks that detect when change notifications have stopped and switch to re-investigation, tokens decreased by 68%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run in Background and View When Needed
&lt;/h3&gt;

&lt;p&gt;This feature had two tasks. One task extracts the first failure from a running build and reports the exit code when finished. The other task cancels a running process and finishes it without leaving anything behind. Regular Codex failed all 6 times. AIShell succeeded 5 out of 6 times. Before considering efficiency, these were the kinds of tasks that couldn't be accomplished through a shell.&lt;/p&gt;

&lt;h3&gt;
  
  
  Batch Change Multiple Files
&lt;/h3&gt;

&lt;p&gt;Before applying, it checks whether the files assumed as the basis for editing have changed; if they have, it stops.&lt;/p&gt;

&lt;p&gt;There were three tasks. Regular Codex succeeded 5 out of 9 times, while AIShell succeeded all 9 times. Comparing tasks where both succeeded, tokens decreased by 33–40%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Show Impact Range of Changes
&lt;/h3&gt;

&lt;p&gt;In tasks that trace direct dependencies, Regular Codex succeeded 0 out of 3 times, while AIShell succeeded all 3 times. In tasks that show impacts from build dependency records, it was 1 vs 3, with a 49% token reduction.&lt;/p&gt;

&lt;p&gt;There was also a task where AIShell failed. It was a task to report "I don't know beyond this point" when untraceable dependencies are mixed in. Regular Codex succeeded 2 times, while AIShell failed all 3 times. There are still gaps in how unknown parts are reported.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results of Extensions to Existing Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Persisting Workspace Folder Memory
&lt;/h3&gt;

&lt;p&gt;AIShell remembers the previous state even after a restart and returns changes that occurred while it was stopped as diffs. For restoration after restart, tokens decreased by 44%. For detecting edits during downtime, tokens decreased by 32%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git State Awareness
&lt;/h3&gt;

&lt;p&gt;Features for comparing branches and worktrees were added as tools. For understanding states with mixed file renames, tokens decreased by 63%. For understanding worktree changes, tokens decreased by 51%. In the task of accurately reporting states where staged and unstaged changes are mixed, Regular Codex failed all 3 times, while AIShell succeeded all 3 times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Configuration Awareness
&lt;/h3&gt;

&lt;p&gt;This feature remembers what the build and test commands for this project are and returns them. It re-learns when package.json changes. For re-learning after configuration changes, tokens decreased by 77%. For scenarios where the remembered content could be used directly, tokens decreased by 46%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Search and Read
&lt;/h3&gt;

&lt;p&gt;In tasks that stream multiple search queries at once, tokens decreased by 54%. In search tasks that trace connections between functions and variables—including the requirement not to return stale analysis results right after edits—Regular Codex succeeded 0 out of 6 times, while AIShell succeeded 5 times.&lt;/p&gt;

&lt;p&gt;There was also a failure here. In the task of reading only as much as fits within a specified amount and returning the rest as a continuation, both failed all 3 times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Around Build and Test Execution
&lt;/h3&gt;

&lt;p&gt;In the task of formatting diagnostic output from execution results into a fixed structure, success was 1 vs 2, with tokens 42% lower. In the task of proposing which tests should be run based on changes and then executing them after waiting for permission, Regular Codex succeeded 0 out of 6 times, while AIShell succeeded 5 times.&lt;/p&gt;

&lt;p&gt;Ineffective tasks also cluster here. In the task of deliberately diagnosing corrupted diagnostic data as broken, AIShell used 30% more tokens than Regular Codex. The feature that reuses previous results when the same check is repeated showed almost no token difference. In scenarios where the information is already available locally, the overhead of going through AIShell remains.&lt;/p&gt;

&lt;h3&gt;
  
  
  Search Past Execution Results
&lt;/h3&gt;

&lt;p&gt;AIShell saves the complete output of executions. For searching for errors across multiple executions, tokens decreased by 48%. For comparing two execution results and listing which warnings appeared and disappeared, tokens decreased by 46%. Regular Codex starts by running the command again to recreate the output, which accounts for this difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuing the Question from Last Time
&lt;/h2&gt;

&lt;p&gt;The previous article started with the question, "With AI, do we even need a shell and terminal?"&lt;/p&gt;

&lt;p&gt;The results this time show that a connection bypassing the shell used fewer tokens, less time, and succeeded in more tasks. At least within the scope of this benchmark, AI produces better results without using a shell.&lt;/p&gt;

&lt;p&gt;Next, I will verify whether the same effects appear in everyday development.&lt;/p&gt;

</description>
      <category>codex</category>
      <category>mcp</category>
      <category>macos</category>
      <category>ai</category>
    </item>
    <item>
      <title>Learning About Shell and Terminal While Developing</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Wed, 05 Aug 2026 00:20:31 +0000</pubDate>
      <link>https://dev.to/quolu/learning-about-shell-and-terminal-while-developing-33d0</link>
      <guid>https://dev.to/quolu/learning-about-shell-and-terminal-while-developing-33d0</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a republication from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;Claude Code 始めました&lt;/a&gt;.&lt;/p&gt;

&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%2Fuupbwakycu60uc40bo15.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%2Fuupbwakycu60uc40bo15.png" alt="A human using a terminal while AI extends structured connections into the computer's interior" width="799" height="381"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Humans use terminals, while AI extends structured connections into the computer's interior&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey, if it's AI, you don't need a shell or a terminal, right?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The development of AIShell started when I said that to an AI.&lt;/p&gt;

&lt;p&gt;I had a vague understanding of shells and terminals. There's an OS, a shell, and a terminal. I use them daily in development, and I knew they were separate things.&lt;/p&gt;

&lt;p&gt;But I didn't really grasp why they were separated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What shells and terminals do
&lt;/h2&gt;

&lt;p&gt;When I looked into it again, a terminal is an application for humans to input characters and see what the computer returns. A shell interprets the commands entered, launches programs, and asks the OS to process them.&lt;/p&gt;

&lt;p&gt;Omitting the finer details, the diagram looks like this:&lt;/p&gt;

&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%2Fahfcwbme6pwpxgxwr3sm.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%2Fahfcwbme6pwpxgxwr3sm.png" alt="The terminal handles character input/output, while the shell interprets commands and asks the OS to process them" width="800" height="256"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The terminal handles character input/output, while the shell interprets commands and asks the OS to process them&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The terminal handles character input/output, and within it, the shell runs. Both are designed for humans to give instructions to the computer and understand the results.&lt;/p&gt;

&lt;p&gt;After researching, I thought, yes, that's exactly right.&lt;/p&gt;

&lt;p&gt;And then it occurred to me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If it's AI, maybe you don't even need a shell.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making AI use transformations meant for humans
&lt;/h2&gt;

&lt;p&gt;When an AI uses a typical development environment, it basically goes through the same path as a human.&lt;/p&gt;

&lt;p&gt;The AI converts what it wants to do into shell format. The execution results are formatted for humans to read in the terminal, and the AI reads them again.&lt;/p&gt;

&lt;p&gt;If we build this for AI, we can pass instructions more directly. The results can also be returned in a form the AI needs for its next decision. This reduces the need to read long human-oriented displays each time, potentially saving tokens and speeding up processing.&lt;/p&gt;

&lt;p&gt;If you truncate long output, the number of characters returned decreases. When necessary lines are missing, the AI starts re-executing or reading more. Rather than methods where the result varies depending on which parts are kept, reducing unnecessary conversions from the start seemed more fundamental.&lt;/p&gt;

&lt;p&gt;It seemed interesting, so I decided to build it while learning. I thought GPT-5.6 could probably make it. Since it directly interacts with the OS, I was slightly concerned about model safety judgments preventing development.&lt;/p&gt;

&lt;h2&gt;
  
  
  I built AIShell
&lt;/h2&gt;

&lt;p&gt;I named what I built simply AIShell. It's a Swift app that runs on Apple Silicon Macs and macOS 15 or later, connecting to the AI via MCP.&lt;/p&gt;

&lt;p&gt;AIShell does not format the requests it receives from the AI into shell strings. It receives the program to execute, arguments, and working folder separately, and launches them directly using macOS features. File operations are also handled via macOS features.&lt;/p&gt;

&lt;p&gt;Git, search programs, compilers, tests, etc., are already excellent. AIShell launches them directly as specified programs, managing execution time, exit status, and output.&lt;/p&gt;

&lt;p&gt;From the AI's perspective, the path looks like this:&lt;/p&gt;

&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%2F9bjatpgca89gumq6feua.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%2F9bjatpgca89gumq6feua.png" alt="A typical AI uses shell commands and human-oriented text, while AIShell exchanges structured instructions and necessary information" width="799" height="521"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;A typical AI uses shell commands and human-oriented text, while AIShell exchanges structured instructions and necessary information&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;During development, I had the opportunity to see the commands AIShell sends directly to the OS and the information returned from the OS. The format differed from the commands and output I usually see in a terminal; the information exchanged directly between AIShell and the OS was laid out before me.&lt;/p&gt;

&lt;p&gt;As I looked at it, I thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I can't understand this at all lol&lt;/p&gt;

&lt;p&gt;I don't want to read it lol&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI was progressing development using those commands and responses. It felt strange. At the same time, I realized for the first time that if an AI can directly handle something that is hard for humans to read, then building AIShell might have meaning.&lt;/p&gt;

&lt;p&gt;Currently, AIShell exposes five features for everyday development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Summarize the current state of the working folder and changes since the last time&lt;/li&gt;
&lt;li&gt;  Read as much as needed from multiple files&lt;/li&gt;
&lt;li&gt;  Search a specified range&lt;/li&gt;
&lt;li&gt;  Run builds or tests and return important diagnostics&lt;/li&gt;
&lt;li&gt;  Read the necessary range from the saved complete output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, even if a build outputs 216KB of diagnostics, it does not pass the full text to the AI every time. AIShell saves the complete output and normally returns the main failure cause and location. When the AI needs additional verification, it can go back to the saved output.&lt;/p&gt;

&lt;p&gt;For files as well, I did not take the approach of re-examining everything each time. AIShell records change notifications from macOS, cross-references them with current file information and SHA-256 hashes, and returns only what has changed since the last time.&lt;/p&gt;

&lt;p&gt;I designed it to reduce the amount shown to the AI in normal use while preserving complete evidence.&lt;/p&gt;

&lt;p&gt;AIShell also manages safety on its own. It only operates on folders authorized by the human, and all features can be stopped from the management app. Deletion sends items to the trash, and before file updates, conflicts are detected using SHA-256 hashes. AIShell also explicitly communicates to the AI's environment the possibility that program execution may update files or communicate over the network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Effects appeared in numbers
&lt;/h2&gt;

&lt;p&gt;After building it, I compared a regular Codex with a Codex using AIShell by giving them the same tasks.&lt;/p&gt;

&lt;p&gt;I used three tasks: a small code change, a compilation failure with a large amount of diagnostics, and a task that repeatedly checks the same working folder. Each was run three times, and both succeeded all nine times.&lt;/p&gt;

&lt;p&gt;The results were as follows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measurement&lt;/th&gt;
&lt;th&gt;Regular Codex&lt;/th&gt;
&lt;th&gt;AIShell&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tokens per successful task&lt;/td&gt;
&lt;td&gt;144,251&lt;/td&gt;
&lt;td&gt;106,955&lt;/td&gt;
&lt;td&gt;-25.86%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average time&lt;/td&gt;
&lt;td&gt;50.14 sec&lt;/td&gt;
&lt;td&gt;33.80 sec&lt;/td&gt;
&lt;td&gt;-32.59%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95th percentile time&lt;/td&gt;
&lt;td&gt;72.49 sec&lt;/td&gt;
&lt;td&gt;43.54 sec&lt;/td&gt;
&lt;td&gt;-39.93%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the task with large diagnostics, tokens decreased by 36.65% and time shortened by 52.01%. This was the task where the mechanism of saving complete diagnostics in AIShell and returning only the main failures to the AI worked most clearly.&lt;/p&gt;

&lt;p&gt;This is a result from three fixed tasks under identical conditions. It does not represent a 25.86% reduction across the entire development. In small tasks, whether the AI used AIShell was not always consistent either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does AI really not need a shell and terminal?
&lt;/h2&gt;

&lt;p&gt;I still don't know.&lt;/p&gt;

&lt;p&gt;The numbers showed effects. In development, I haven't been able to use it much yet. I am currently using it in the development of the dotagents project while fixing bugs found along the way.&lt;/p&gt;

&lt;p&gt;I, who only vaguely understood shells and terminals, built AIShell while learning from the AI. Through this, I finally grasped the mechanisms designed for humans to use computers.&lt;/p&gt;

&lt;p&gt;The question I first posed to the AI still has no answer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey, if it's AI, you don't need a shell or a terminal, right?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For now, it might not need them. I'll keep using it a bit more and find out.&lt;/p&gt;

</description>
      <category>codex</category>
      <category>mcp</category>
      <category>macos</category>
      <category>ai</category>
    </item>
    <item>
      <title>As AI Gets Smarter, My Craft Becomes Outdated—So I Thought, and I Checked</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Tue, 04 Aug 2026 00:20:23 +0000</pubDate>
      <link>https://dev.to/quolu/as-ai-gets-smarter-my-craft-becomes-outdated-so-i-thought-and-i-checked-1e95</link>
      <guid>https://dev.to/quolu/as-ai-gets-smarter-my-craft-becomes-outdated-so-i-thought-and-i-checked-1e95</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a reprint from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;I've Started Using Claude Code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Fable 5—the smartest model available, but only for a limited time—will end its run on July 7th. A little before that, the same story was circulating on X. Use this smart model while you can to build your development environment; invest before it disappears. People were sharing configuration files and diagramming how to use different models. Everyone was trying to take that intelligence out of their own environment.&lt;/p&gt;

&lt;p&gt;My interest was one step before that. There was something that had been nagging at me. If AI keeps getting smarter at this speed, won't the tricks I've built up become obsolete with each new model, eventually making all of them unnecessary? If so, investing time in current tricks would be a waste.&lt;/p&gt;

&lt;p&gt;So, while the smartest model was available, I decided to use it. I wanted to see whether my accumulated knowledge was already outdated.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Verified the Hype with Official Documentation
&lt;/h2&gt;

&lt;p&gt;To put the claims floating around on X into one sentence: "You can't buy intelligence itself, but you can transfer the patterns of smart behavior to cheaper models through certain configurations." The idea was to solidify your workflow with the smart model while you can, then have the cheaper model replicate the same behavior.&lt;/p&gt;

&lt;p&gt;I wondered if it were really that simple. If copying behavior alone transfers intelligence, that would be ideal. I've built up my environment quite a bit. I checked the official documentation to see if it could really be transferred.&lt;/p&gt;

&lt;p&gt;What I found was two things. First, for smart models, giving overly detailed instructions can actually degrade quality. For older models, detailed notes might be helpful, but for smart models they become obstacles—consider removing them. Second, those "patterns of behavior" were explicitly called out as something to consolidate in a constitution file (CLAUDE.md) that you pass to the AI. The transfer discussion was about bringing that into a different configuration.&lt;/p&gt;

&lt;p&gt;It turns out that adding instructions to a smart model isn't the right approach. The smarter the model, the better it is to give just the key points and let it handle the rest, rather than micromanaging. If the official docs are correct, we should be moving toward removal. But where and how much to remove? Deciding what's "unnecessary" myself would mix in attachment and bias. So I didn't make the decision myself; I left it to Fable and the verification process it runs. I just watched what happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Had My Own Constitution Attacked for Deletion
&lt;/h2&gt;

&lt;p&gt;That verification used a method where a separate AI deliberately presents counterarguments to try to tear down the original claims (let's call this role the "refuter"). Fable took my constitution (a global CLAUDE.md that compiled all the practices I wanted the AI to follow) and distributed it to eleven refuters, having each read it in the same way. "These are excessive instructions for old models, garbage that a smart model no longer needs. Identify clauses that can be deleted, and go ahead and delete them." With deletion as the goal, eleven refuters read the constitution separately.&lt;/p&gt;

&lt;p&gt;The result was unexpected. Not a single clause could be purely deleted. Every one served some purpose. Moreover, five clauses that seemed obvious—ones I thought wouldn't hurt to remove—the refuters actually pushed back, saying "these are necessary." Left to its own devices, a smart model tends to ramble and do things you didn't ask for. Those five clauses specifically curbed that tendency. For example, one rule: "only do what was asked, don't expand on your own." It seemed obvious, but the refuter showed that removing it would cause the smart model to start expanding its own work. The more obvious something is, the more it needs to be written down and enforced.&lt;/p&gt;

&lt;p&gt;This was the first answer. In light of a smarter model, my accumulated knowledge wasn't outdated. I tried to delete what I thought could be removed, and everything survived.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Consolidated Scattered Projects from a Single Seat
&lt;/h2&gt;

&lt;p&gt;The fact that the constitution survived intact meant that the practices I'd accumulated since February were still effective. To make those practices work across all projects, the folder structure and workflow needed to be consistent. But my projects had diverged in approach since February, with different structures and workflows depending on the machine. So, while I was reviewing the constitution, I also standardized the projects. Looking across all machines, I found about fifty project folders. Leaving them as-is would cause trouble later. Among them, I standardized eighteen active projects into a common template in one day.&lt;/p&gt;

&lt;p&gt;Going through fifty folders alone would be impractical. What helped here was a tool I'd built earlier (&lt;a href="https://dev.to/quolu/ai-to-ai-conversations-the-interactive-terminal-powered-by-aiterm-mcp-2i6l"&gt;aiterm&lt;/a&gt;). I designated one seat for issuing commands (in my case, a configuration project). The smart model sitting there would call, via aitem, the Claude instance running in each project's folder. The called instance would work with full knowledge of that project's contents. If I'd tried to rewrite everything remotely without knowing the contents, I'd likely break things. Because each project's designated handler worked with its own context, the work remained grounded.&lt;/p&gt;

&lt;p&gt;Which project to assign to which AI? This allocation I left to the smart model in the command seat. I only gave the policy: to save costs and available usage, use several cheaper AIs (e.g., Codex for reviews, another AI for bulk rewrites). Initially, the allocation wasn't working well. So I gradually added requirements, and each time it worked, I recorded the allocation method in the constitution file. I repeated the cycle of fixing and recording, cultivating it. The next time a similar task came up, the recorded knowledge allowed it to be allocated more intelligently from the start. I also subjected this tool itself to the same refuter process later, to scrub it of flaws once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Even When the Model Switched Midway, Work Didn't Stop
&lt;/h2&gt;

&lt;p&gt;On July 4th, I ran the smart model fully for one day and had largely built the foundation up to that point: how to orchestrate multiple AIs, project standardization, the configuration project, and the aiterm tool. The next day, the 5th, the smart model quota was exhausted. From there on, I switched to the usual model (Opus).&lt;/p&gt;

&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%2Fvdqid22j9n6yhln9lwx7.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%2Fvdqid22j9n6yhln9lwx7.png" alt="Models are replaceable parts; accumulated ingenuity and structure remain. The role-to-model mapping table, folder templates, trap records, and practice constitution form the foundation, so work doesn't stop even when the model is switched." width="800" height="440"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Models are replaceable parts; accumulated ingenuity and structure remain. The role-to-model mapping table, folder templates, trap records, and practice constitution form the foundation, so work doesn't stop even when the model is switched.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Even after the switch, work didn't stop. The usual model ran through and completed the remaining finishing work. This was because everything was built from the start to work with any model. There are three ways to make the design model-agnostic.&lt;/p&gt;

&lt;p&gt;First, write the model name in only one place. Have a single mapping table that says "for this role, use the strongest current model," and don't write dated model names in code or rules. When the model generation changes, rewriting that one sheet updates everything.&lt;/p&gt;

&lt;p&gt;Second, standardize project folders to the same template. Locations are fixed—design decisions go here, research findings go there—so an AI entering a project for the first time, regardless of model, can look at the same places and work.&lt;/p&gt;

&lt;p&gt;Third, have a mechanism to remember traps you've once fallen into. Record them so they can be referenced to avoid repeating the same mistakes—so even when switching to a new model, you carry forward the traps the previous model encountered.&lt;/p&gt;

&lt;p&gt;None of these rely on the intelligence of a specific model. What's worth building while you have access to a smart model is this kind of design that outlasts model changes. The proof is the fact that even with a mid-course model switch, the work ran to completion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enforcing Rules Through Friction
&lt;/h2&gt;

&lt;p&gt;With the same thinking as making mechanisms model-agnostic, I also changed how rules are enforced. As work progressed, a hole appeared in my approach. Even though my AI was the orchestrator, it sometimes hoarded routine tasks (writing many tests, creating configuration files) that should have been delegated to cheaper AIs, consuming its expensive quota. The rule was clear: pass routine tasks to cheaper AIs, and let the orchestrator focus solely on decisions. It was decided, but unless told, it wasn't followed.&lt;/p&gt;

&lt;p&gt;Writing "be careful" in prose requires willpower to follow. Willpower, left unchecked, loses to the path of least resistance. So I made the desired behavior the default, and added friction to the lazy option. Before starting to write code, the AI must always label each task as either "do it myself" or "delegate to a cheaper AI." If deciding to do it themselves, they must write one line explaining why. Because writing a reason is bothersome, the default naturally shifts toward "delegate." Additionally, I set up an automated mechanism to inject a memo reminding them of this practice the moment a plan is approved.&lt;/p&gt;

&lt;p&gt;What's injected is just a reminder memo. Whether it's followed depends on the reading AI—if ignored, it slips through. As for the pre-work labeling, it's still only written in prose and hasn't been mechanized to fire automatically. This is the weakest point. In the process of turning rules into mechanisms, half has become mechanized, and half remains just words.&lt;/p&gt;

&lt;p&gt;I previously wrote about giving up writing "be careful" to the AI and instead reinforcing it from the outside with three mechanisms (&lt;a href="https://dev.to/quolu/stop-telling-claude-to-be-careful-reinforcing-it-from-the-outside-with-3-tools-2k8k"&gt;The Story of Giving Up Writing 'Be Careful' to Claude and Reinforcing It from the Outside with Three Things&lt;/a&gt;). This time's rule mechanism is a continuation of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Remained
&lt;/h2&gt;

&lt;p&gt;The worry I had before starting—that my know-how would become obsolete as AI gets smarter—didn't happen for these two days. The accumulated ingenuity, even when scrutinized by a smarter model, all survived. The assembled mechanisms completed without stopping even when the model was switched midway. What newly remained from having access to a smart model was the design that outlasts the model itself, and the allocation method cultivated through repeated fixing and recording.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>llm</category>
    </item>
    <item>
      <title>Implementing Orchestration</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:11:32 +0000</pubDate>
      <link>https://dev.to/quolu/implementing-orchestration-jhf</link>
      <guid>https://dev.to/quolu/implementing-orchestration-jhf</guid>
      <description>&lt;p&gt;I used to think that if you let the smartest model do everything, you'd get the best results. That's how I was running things for a while. But when you keep doing that, the quota runs out quickly, and it often crashes.&lt;/p&gt;

&lt;p&gt;When I assigned heavy work to Codex's top mode (Sol Ultra), I used up five hours' worth of quota in one hour. That happened three times in a row. Even with the strongest Claude approach, doing this every day hits the limit. Plus, Opus frequently fails when calling tools. The longer you run it, the worse it gets, and when it gets stuck, the work stops there.&lt;/p&gt;

&lt;p&gt;So I stopped leaving everything to a single model. I decided to sort the tasks and distribute them to separate agents. This way of distributing and bundling AI work is apparently called orchestration.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, sort the work into three categories
&lt;/h2&gt;

&lt;p&gt;Before moving a muscle, I decide which category the task at hand falls into. There are only three labels.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;F (fatal)&lt;/strong&gt; = Work that would break things if done wrong. Authentication, money or data transactions, externally exposed parts, operations that touch the production server. This I write directly myself (as the orchestrator).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;A (auto)&lt;/strong&gt; = Work that is predetermined and involves many steps. Certain types of tests, configuration files, repetitive replacements. This I outsource.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;H (human)&lt;/strong&gt; = Work that humans do. My territory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default is A. Unless it's something that would break badly, I outsource it. I have a habit of taking everything on myself if left unchecked, so I made outsourcing the default, and added a remark to explain why I'm keeping it in-house only when I decide to write it myself. I made it more cumbersome to hold onto tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the destination from models that don't use Claude's quota
&lt;/h2&gt;

&lt;p&gt;When outsourcing, I have a priority order for choosing. First, I pick from &lt;strong&gt;models that don't use Claude's quota&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I run the orchestrator on Claude. Claude has a limited amount it can use per day. If I also run high-volume tasks on Claude, the quota for the crucial orchestrator role diminishes. So for the legwork tasks, I first send them to Codex (OpenAI subscription) and Grok (xAI subscription). These two don't consume any of Claude's quota. Claude also has cheaper models, but they use the same quota, so I prioritize them later.&lt;/p&gt;

&lt;p&gt;Which model to assign is determined by two factors: the intelligence tier and the depth of thinking. Often, having a smart model think lightly is cheaper and yields better results than having a medium model think long. When in doubt, I assign to the cheaper one. If the cheap assignment isn't enough, I can upgrade later, but starting high means the quota spent is lost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bind the four in a single terminal
&lt;/h2&gt;

&lt;p&gt;Claude, Codex, Composer, and Grok. I bind these four together into a single persistent terminal using a custom system called aiterm.&lt;/p&gt;

&lt;p&gt;This is also significant from a cost perspective. All four run while logged in under a monthly subscription. They don't go through a pay-per-use (API) system. So no matter how many high-volume tasks I throw at them, the cost doesn't keep rising. I run the four in parallel within the subscription quota.&lt;/p&gt;

&lt;p&gt;I have also added a consultation window called Oracle. It runs on a ChatGPT subscription, which is a separate account from the Codex quota. It cannot write files, but it excels at thinking purely and returning opinions. When I'm unsure about a design, I can double-check it with another model without reducing the Codex quota.&lt;/p&gt;

&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%2Fx7gs1tsung10d3x181r5.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%2Fx7gs1tsung10d3x181r5.png" alt="Requests pass through the initiation gate, and the orchestrator decides the sorting and placement. Legwork tasks are first sent externally (Codex, Grok) to avoid using Claude's quota, while Oracle is connected as a separate consultation-only window. Results are verified at the orchestrator's gate before returning to storage and recording." width="800" height="734"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Requests pass through the initiation gate, and the orchestrator decides the sorting and placement. Legwork tasks are first sent externally (Codex, Grok) to avoid using Claude's quota, while Oracle is connected as a separate consultation-only window. Results are verified at the orchestrator's gate before returning to storage and recording.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The rules weren't followed just by writing them down
&lt;/h2&gt;

&lt;p&gt;The sorting and distribution methods up to this point were all written down as rules. But writing them wasn't enough to enforce them.&lt;/p&gt;

&lt;p&gt;The orchestrator AI would bypass the written rules, hoarding high-volume tasks itself or continuing to run on the most expensive model. The document was only read at the beginning of a session, and by the time the AI was actually moving, it had slipped its mind.&lt;/p&gt;

&lt;p&gt;So I decided to remind it at the moment of action. I introduced a mechanism (hook) that inserts a fixed reminder at task milestones, right before starting implementation: "Declare whether this task is F, A, or H, and which model to assign it to, in one line." I stopped trying to make it read and instead placed the reminder where it would stop the action.&lt;/p&gt;

&lt;p&gt;There was one side effect. Creating and updating ToDos had also often been neglected. By inserting a reminder using the same method, this also started working.&lt;/p&gt;

&lt;h2&gt;
  
  
  For now, this has settled things
&lt;/h2&gt;

&lt;p&gt;Rather than running just one smartest model, I distribute tasks to moderately capable models and hold onto only the key parts myself. I separate the quotas and rotate them within each subscription. Decisions are inserted as reminders right before action.&lt;/p&gt;

&lt;p&gt;The models I'm running are all smart. On top of that intelligence, I decide everything myself: which task to assign to whom, which quota to use, and when to send reminders. If smarter models appear, I can just swap out the destinations. The mechanism itself doesn't change.&lt;/p&gt;

&lt;p&gt;Rather than having one model do everything, distributing and retaining control seems to suit my way of working.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>codex</category>
      <category>grok</category>
    </item>
    <item>
      <title>I Suspected My App Had Flaws, So I Consulted Fable 5</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:10:53 +0000</pubDate>
      <link>https://dev.to/quolu/i-suspected-my-app-had-flaws-so-i-consulted-fable-5-565n</link>
      <guid>https://dev.to/quolu/i-suspected-my-app-had-flaws-so-i-consulted-fable-5-565n</guid>
      <description>&lt;p&gt;I created a tool called &lt;code&gt;aiterm-mcp&lt;/code&gt; and published it on npm. It allows an AI to hold a persistent terminal and even operate another AI from there. The story behind it is written in &lt;a href="https://dev.to/quolu/released-aiterm-mcp-on-npm-an-mcp-server-to-reduce-token-usage-by-providing-ai-with-a-persistent-a5n"&gt;the article when I announced it&lt;/a&gt; and &lt;a href="https://dev.to/quolu/ai-to-ai-conversations-the-interactive-terminal-powered-by-aiterm-mcp-2i6l"&gt;the article about AIs conversing with each other&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Recently, this tool has become the center of my development environment. My current setup consists of Fable 5 (Claude's new top-tier model) directing the overall workflow and assigning tasks to Codex and Grok, and all those instructions go through aiterm. When I posted an introduction in English, I started getting responses from overseas. One person evaluated the environment verification before startup, and someone else said, "The ability to maintain a single terminal is more effective than the part where AI drives AI." In the Japanese community, people actually started using it and shared configuration tips.&lt;/p&gt;

&lt;p&gt;Even so, the responses were only a few, so I thought almost no one had noticed this tool. When I checked the numbers to write this article, I was surprised to see that &lt;a href="https://www.npmjs.com/package/aiterm-mcp" rel="noopener noreferrer"&gt;npm downloads&lt;/a&gt; were 1,416 in the last 30 days. Apparently someone somewhere is installing it every day.&lt;/p&gt;

&lt;p&gt;Given that, I've fixed it many times. But no matter how many times I fixed it, I felt like there were still some rough edges somewhere. I couldn't even say what was wrong; all tests passed, and there were no specific bugs I could name. There was a lingering sense of not fully trusting it.&lt;/p&gt;

&lt;p&gt;So I decided to consult Fable 5. I just said something like "polish it up" without specifying where to look or what to fix. Looking back, it was a pretty vague request.&lt;/p&gt;

&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%2Fewsluvwbl94b3yxy3gu6.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%2Fewsluvwbl94b3yxy3gu6.png" alt="The consultation was just one sentence. The audit was assembled based on written rules of thumb (the flow of this incident)" width="800" height="401"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The consultation was just one sentence. The audit was assembled based on written rules of thumb (the flow of this incident)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When it came back, it was done
&lt;/h2&gt;

&lt;p&gt;In my environment, I have rules of thumb accumulated over several months. When auditing, have multiple perspectives search in parallel. For each issue that surfaces, pass it to a different AI to question it, and adopt only those that survive. Before touching the code, prepare tests first and run them automatically. After fixing, actually run it to verify. All these are rules I established after painful experiences, and I've written about them in previous articles.&lt;/p&gt;

&lt;p&gt;Fable 5 read these rules and assembled the audit on its own. Seven AIs acting as searchers ran in parallel from different perspectives, each issue had a refuter attached, and even an AI to catch oversights—totaling 27 agents. It also showed the code to three external AI systems (GPT-5.6, Grok 4.5, and Composer), and the issues from there were further challenged by six refuters. It took 12 minutes, and the processing amount was 1.34 million tokens (the unit of reading/writing for AI).&lt;/p&gt;

&lt;p&gt;Seventeen raw issues came out, and seven survived the refutation. Combined with issues that survived external review, everything was fixed, and the tool went from v0.11 to v0.12.1 that same day. Regression tests increased from 183 to 197. That day, I wrote basically just the first sentence; the rest was driven by the accumulated rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  The feeling was right
&lt;/h2&gt;

&lt;p&gt;There really were rough edges. I'll introduce just two of what was found.&lt;/p&gt;

&lt;p&gt;The first was that the check to stop dangerous commands could be bypassed. Aiterm has a mechanism that asks for confirmation when a dangerous command like &lt;code&gt;rm -rf /&lt;/code&gt; (command to delete everything on disk) is about to be sent. The matching pattern didn't account for the standard &lt;code&gt;--&lt;/code&gt; notation, so &lt;code&gt;rm -rf -- /&lt;/code&gt; (with two hyphens) passed through the check. The fix was a single line.&lt;/p&gt;

&lt;p&gt;The second was a cleanup omission. If a process is forcefully terminated while waiting for an AI's response, a flag file saying "currently waiting" remains. There was no code anywhere to clean up this flag, and if it remained, subsequent waits on the same terminal would be permanently rejected. Codex and Claude's audits independently pointed out the same spot without knowing each other.&lt;/p&gt;

&lt;p&gt;The refuters also did their job. The ten discarded issues were plausible mistakes. For example, one issue said, "If writing to the management file is interrupted, the remnants become unmanageable." But reading the code again, there was already an escape path that allowed operation as a normal terminal even with a corrupted management file, and the time window for the problem was on the order of microseconds. If I had swallowed it and added countermeasure code, it would have become unnecessarily complex.&lt;/p&gt;

&lt;p&gt;There's a supporting evidence for this "separate challenger" step from a paper this April. A report showed that over 80 AI agents unanimously confirmed a non-existent vulnerability in OpenSSL as real, proving that collecting numbers of AI suggestions doesn't guarantee correctness. Our "17 reduced to 7" is a smaller version of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bug none of the 27 could find
&lt;/h2&gt;

&lt;p&gt;The most troublesome bug was not found by this audit.&lt;/p&gt;

&lt;p&gt;Aiterm determines whether an AI has "finished speaking" by checking if the screen output has stopped increasing for 0.5 seconds. This judgment has a timing gap: the moment when the output volume is measured and the moment when the screen state is checked are slightly out of sync. When output arrived in that gap, the fact that it ended was correctly captured, but the record of "how it ended" sometimes differed from reality.&lt;/p&gt;

&lt;p&gt;On my local Mac, all tests pass. I found this through GitHub CI (a system that automatically runs tests on multiple operating systems with each code update). The macOS runner on CI is very slow. The problematic test had a wait time of 0.6 seconds versus a stillness threshold of 0.5 seconds, leaving only 100ms of margin. On the slow runner, this slack wasn't enough, and the macOS job consistently failed. That's when I first learned about the bug.&lt;/p&gt;

&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%2Frpbdjaaiegn0cfup1rwa.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%2Frpbdjaaiegn0cfup1rwa.png" alt="Actual CI screen during v0.12.0 release. Linux and Windows all passed, macOS node 18 failed, and the other two macOS jobs were automatically aborted" width="800" height="498"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Actual CI screen during v0.12.0 release. Linux and Windows all passed, macOS node 18 failed, and the other two macOS jobs were automatically aborted&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The interesting part is that the audit came close. The AI responsible for catching oversights noticed the category of "time-dependent risky tests" and had actually pointed out another test. That test had a 5x margin, so it was judged "no problem," which was correct. The real one remained unpointed. When just reading the code, a test with a 1.2x margin and one with a 5x margin both look like "passing tests."&lt;/p&gt;

&lt;p&gt;By the way, this CI was running even before the audit. I had decided from past failures to have automated tests on multiple OSes before touching the code, and I followed that this time too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bugs that only appeared when running
&lt;/h2&gt;

&lt;p&gt;Apart from the desk audit, there were two bugs found the same day during "actual running verification."&lt;/p&gt;

&lt;p&gt;When I fetched Grok's screen log in "read all" mode, 73,176 characters came back packed into 4 lines. Output from tools that redraw the screen typically has almost no line breaks. Aiterm's folding feature was designed to activate when "the number of lines exceeds 60," so these huge 4 lines passed through unfolded, exceeded Claude's per-message capacity, and the reading itself failed. On paper, the folding feature looks perfectly functional. The case where the length of a single line becomes problematic didn't come up from any of the 27 agents until I actually ran the real Grok.&lt;/p&gt;

&lt;p&gt;The other was missing parts of long responses. When an AI's response is long, aiterm returns only the last screenful (about 24 lines). For a 40-line response, only lines 18 onward were captured, and there was no way to retrieve the first half. I solved this by creating a new feature to recover the full response from the AI's conversation history.&lt;/p&gt;

&lt;p&gt;These two issues didn't surface from just reading the code. They only appeared when actually running it with real data flowing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who found what
&lt;/h2&gt;

&lt;p&gt;The results line up as follows:&lt;/p&gt;

&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%2F050hrvj17abqroxarnj4.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%2F050hrvj17abqroxarnj4.png" alt="Who found what (AI audit / multi-OS CI / actual running verification)" width="800" height="439"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Who found what (AI audit / multi-OS CI / actual running verification)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This all got moving from a vague sentence because Fable 5 read the rules accumulated over several months. The "rough edges" I couldn't name materialized as 7 issues and disappeared in a day. The refutation step stopped 10 dangerous assumptions before implementation. And the most troublesome bug was found by the rules my past self had set: having CI in place first, and actually running to verify after fixing.&lt;/p&gt;

&lt;p&gt;The bugs found did not overlap at all among these three methods. Hmm. I wonder what that means.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>ci</category>
    </item>
    <item>
      <title>How Codex's Top-Tier Mode Burned Through a 5-Hour Quota in 1 Hour</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:10:19 +0000</pubDate>
      <link>https://dev.to/quolu/how-codexs-top-tier-mode-burned-through-a-5-hour-quota-in-1-hour-51o2</link>
      <guid>https://dev.to/quolu/how-codexs-top-tier-mode-burned-through-a-5-hour-quota-in-1-hour-51o2</guid>
      <description>&lt;p&gt;While I was enjoying Fable 5, Claude hit its one-week quota limit. Just then GPT-5.6 came out, so this time I decided to use Sol from Codex. I chose the top-tier Ultra.&lt;/p&gt;

&lt;p&gt;In one hour, five hours' worth of quota disappeared. This happened three times in a row.&lt;/p&gt;

&lt;p&gt;At first, I thought I was overusing it. I was throwing heavy tasks at it in batches, and sometimes that's just how it goes. But the third time, it felt too fast. Using up five hours of quota in one hour is too fast, even for heavy tasks. I opened the logs to see what was eating it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking at the logs, all the children were using the top model
&lt;/h2&gt;

&lt;p&gt;Codex has a mechanism where a single task can be divided among child AI agents (sub-agents). When you throw a heavy task at it, Sol spawns several children and runs them in parallel. When I opened the logs, all those children were running on Sol's Ultra.&lt;/p&gt;

&lt;p&gt;I have configuration files in &lt;code&gt;~/.codex/agents/&lt;/code&gt; that assign models based on roles. For example, a child doing research uses a cheaper model, a child implementing uses a mid-range one, and so on. But when I looked at the logs, none of that configuration was taking effect. The command to spawn a child (&lt;code&gt;spawn_agent&lt;/code&gt;) only accepts a &lt;code&gt;task_name&lt;/code&gt; — there’s no field for role or model selection. So the role remained empty (&lt;code&gt;agent_role&lt;/code&gt; was empty), and the model was simply inherited from the parent. Everyone was on Sol Ultra.&lt;/p&gt;

&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%2Fs3pi74zp1h12gwan6txp.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%2Fs3pi74zp1h12gwan6txp.png" alt="The parent Sol/Ultra spawns multiple children, and the children spawn more children. Since the model specification isn’t passed down, all subordinate children end up on the same Sol/Ultra" width="799" height="435"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The parent Sol/Ultra spawns multiple children, and the children spawn more children. Since the model specification isn’t passed down, all subordinate children end up on the same Sol/Ultra&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you run a single top-tier model, multiple other top-tier models hang off it. If a child calls another child, the number multiplies. This was why five hours of quota disappeared in one hour. My carefully configured role-based assignments to keep costs down were completely bypassed, and everything was running at the highest price.&lt;/p&gt;
&lt;h2&gt;
  
  
  The model selection option was hidden
&lt;/h2&gt;

&lt;p&gt;Why wasn't the configuration working? The spawn command simply had no field for specifying the model.&lt;/p&gt;

&lt;p&gt;Codex's configuration has a setting called &lt;code&gt;hide_spawn_agent_metadata&lt;/code&gt;. The default is to hide it (&lt;code&gt;true&lt;/code&gt;). This "metadata" includes fields for selecting the model and the depth of thinking. So with the default settings, those fields were removed from the spawn command entirely. Without those fields, no matter how much I configured role-based models, they couldn't be passed on. Since they couldn't be passed, the children just inherited the parent's model. The higher-tier model you chose, the more your children all ran at the top tier.&lt;/p&gt;

&lt;p&gt;I thought that choosing the top mode would let the smart model smartly delegate tasks. In reality, just silently selecting it meant even lightweight tasks continued running on the top-tier model.&lt;/p&gt;
&lt;h2&gt;
  
  
  The same reports were lined up on the same day
&lt;/h2&gt;

&lt;p&gt;I wondered if this was just my environment, so I looked into it. From July 9th to 10th, on X, the same reports appeared in both Japanese and English. People said that leaving Sol Ultra alone caused them to hit the quota limit in three minutes. Five hours of quota disappeared in 20 minutes. They hit the five-hour limit twice in one day — something that had never happened before.&lt;/p&gt;

&lt;p&gt;The diagnosis was consistent too. Someone wrote exactly what I saw in the logs: "&lt;code&gt;spawn_agent&lt;/code&gt; only sends the task name. The child inherits the parent model with an empty role, ignoring the configuration file." An issue on GitHub also summarized it: with Sol, you can't specify a model for children, so all children end up on Sol. Some pointed out it was a bug introduced in version 0.144.1.&lt;/p&gt;

&lt;p&gt;There was also a post describing how to fix it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enabling Model Selection for Children with Two Configuration Lines
&lt;/h2&gt;

&lt;p&gt;A user named evi77ain posted two lines of configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[features.multi_agent_v2]&lt;/span&gt;
&lt;span class="py"&gt;hide_spawn_agent_metadata&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;tool_namespace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"agents"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line restores the hidden model selection field. The second line is to avoid errors caused by conflicting names for the tool that spawns children. After adding these two lines to &lt;code&gt;config.toml&lt;/code&gt; and restarting the session, the model field returned to the spawn command.&lt;/p&gt;

&lt;p&gt;After it was restored, the role-based assignments I had placed in &lt;code&gt;~/.codex/agents/&lt;/code&gt; started working as intended. When I actually specified a role and spawned a child, it ran on the cheaper model as configured. The situation changed from everything running on the top-tier model to only the necessary parts running on the top-tier model and the rest using cheaper models. The rate at which quota decreased also returned to normal.&lt;/p&gt;

&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%2Ff81iwf2ob7twevdjcxfu.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%2Ff81iwf2ob7twevdjcxfu.png" alt="Before: both parent and children are all Sol/Ultra, causing quota to drain rapidly. After: the parent is Sol, children are assigned to cheaper models by role (research uses a light model, implementation uses a mid-range one), and the drain slows down" width="800" height="387"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Before: both parent and children are all Sol/Ultra, causing quota to drain rapidly. After: the parent is Sol, children are assigned to cheaper models by role (research uses a light model, implementation uses a mid-range one), and the drain slows down&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Just Picking the Top Tier Wasn't Enough
&lt;/h2&gt;

&lt;p&gt;I added two lines of configuration to allow selecting a cheaper model for children. For now, things have settled down. But honestly, OpenAI — don't you think this kind of hidden parameter is a bit off?&lt;/p&gt;

</description>
      <category>codex</category>
      <category>openai</category>
      <category>claudecode</category>
    </item>
  </channel>
</rss>
