<?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: Lugiax</title>
    <description>The latest articles on DEV Community by Lugiax (@lugia123).</description>
    <link>https://dev.to/lugia123</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%2F4126701%2F15d26365-28c2-4c77-a294-421ddfac1ae8.png</url>
      <title>DEV Community: Lugiax</title>
      <link>https://dev.to/lugia123</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lugia123"/>
    <language>en</language>
    <item>
      <title>Nobody Hand-Writes Assembly Anymore. Why Are You Still Reviewing 2,000-Line AI Diffs?</title>
      <dc:creator>Lugiax</dc:creator>
      <pubDate>Wed, 28 Oct 2026 13:06:03 +0000</pubDate>
      <link>https://dev.to/lugia123/nobody-hand-writes-assembly-anymore-why-are-you-still-reviewing-2000-line-ai-diffs-4484</link>
      <guid>https://dev.to/lugia123/nobody-hand-writes-assembly-anymore-why-are-you-still-reviewing-2000-line-ai-diffs-4484</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; In 1957, IBM released Fortran, and veteran engineers furiously swore they would never trust machine-generated assembly without manual verification. Today, history is repeating itself. High-level languages are quietly becoming the new machine code. Staring bloodshot-eyed at a 2,000-line AI git diff isn't rigorous engineering—it's performative security theater. Here is why the old Code Review paradigm is dead, how the "Three Defenses" replace it, and how combining &lt;strong&gt;agy (Antigravity CLI)&lt;/strong&gt; with multi-agent orchestration tools like &lt;strong&gt;Polter&lt;/strong&gt; gives us our sanity back.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;In 1957, IBM unveiled something that shook the computing world to its core: &lt;strong&gt;Fortran&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It was the world’s first true high-level programming language.&lt;/p&gt;

&lt;p&gt;Before Fortran, writing software was an exercise in pure masochism. Programmers spent their days hunched over desks, punching binary machine code and raw assembly mnemonics into paper cards and punch tapes—manually dictating every single memory address, accumulator shift, and hardware register.&lt;/p&gt;

&lt;p&gt;When John Backus and his team introduced Fortran, their promise sounded almost utopian:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"You no longer need to remember machine registers or memory offsets. Just write mathematical formulas resembling plain English sentences, and the compiler will translate them into raw machine instructions for you."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How do you think the elite programmers of 1957 reacted?&lt;/p&gt;

&lt;p&gt;Did they throw a party? Did they celebrate their newfound freedom?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not a chance.&lt;/strong&gt; They hated it.&lt;/p&gt;

&lt;p&gt;Computing journals and academic labs erupted in righteous indignation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"The code emitted by the compiler is bloated and slow!"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"No mechanical program could ever optimize memory better than a seasoned human!"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"If I didn't hand-craft every single opcode myself, I cannot trust it. Every line of emitted assembly must be manually verified!"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yet, the freight train of history didn't care about their bruised egos.&lt;/p&gt;

&lt;p&gt;Within a few short years, virtually all business and scientific computing migrated to high-level languages. Fast forward to today: unless you are writing bare-metal micro-controllers, Linux kernel drivers, or compiler backends, &lt;strong&gt;nobody hand-writes assembly anymore. And nobody on your team asks you to review the compiler’s assembly output before pushing a PR.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why? Because the software industry learned a permanent truth:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Once an abstraction ladder goes up, it never comes back down.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And right now, in 2026, the pendulum of history has swung straight back to the exact same spot.&lt;/p&gt;

&lt;p&gt;When an LLM spits out 2,500 lines of pristine TypeScript, Go, or Python in four seconds, millions of developers still sit glued to their monitors at midnight, eyes stinging, scrolling line-by-line through a monstrous git diff.&lt;/p&gt;

&lt;p&gt;We seem to have forgotten: &lt;strong&gt;Our programming languages are rapidly degrading into modern-day assembly.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Cognitive Trap: Inspecting AI Code Like It's 1995 Assembly
&lt;/h2&gt;

&lt;p&gt;Whenever I tell people that "Python is the new assembly," their gut reaction is almost always defensive:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Are you crazy? High-level languages have rigid syntax, type safety, and semantic structure! We write code, AI writes code—how can you compare TypeScript to raw machine hex?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To see why this comparison holds up, we need to understand how technical abstractions actually evolve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Core Rule&lt;/strong&gt;: Computing history is just the story of putting thicker and thicker lids on underlying complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Automobile Analogy&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gen 1 (The Hand-Crank Era)&lt;/strong&gt;: In the early 1900s, starting a car meant walking to the front bumper, inserting an iron crank, and manually spinning the crankshaft. Drivers had to understand spark timing and valve compression just to leave the driveway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gen 2 (The Ignition Key &amp;amp; Automatic Transmission)&lt;/strong&gt;: Turn a key, press the gas pedal, and drive. You don’t know—or care—which microsecond the third cylinder's spark plug fired.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gen 3 (Autonomous Driving)&lt;/strong&gt;: You slide into the back seat and say: &lt;em&gt;"Take me to the nearest airport, and avoid the toll roads."&lt;/em&gt; If you still spend the entire ride anxiously monitoring whether the steering rack is turning at 14.2 degrees or 14.5 degrees, you aren't being safe; you're just exhausting yourself.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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%2Fs0pbxg3dpyko8q84p87d.jpg" 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%2Fs0pbxg3dpyko8q84p87d.jpg" alt="The Abstraction Ladder: When programming languages become the new assembly" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  When Keyboard Typing Cost Hits Zero, Syntax Reviews Collapse
&lt;/h3&gt;

&lt;p&gt;Why did we spend the last thirty years worshipping at the altar of the Pull Request Code Review?&lt;/p&gt;

&lt;p&gt;Because code was written by &lt;strong&gt;meatware&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Humans are slow, clumsy typists prone to fatigue. We accidentally write &lt;code&gt;=&lt;/code&gt; instead of &lt;code&gt;==&lt;/code&gt;, we introduce off-by-one errors on Friday afternoons, and we forget null checks. Peer review was an effective linting net for human fallibility.&lt;/p&gt;

&lt;p&gt;With AI, the dynamic has completely flipped:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Throughput Asymmetry&lt;/strong&gt;: A state-of-the-art agent like &lt;code&gt;agy&lt;/code&gt; (Google Antigravity CLI) or Claude can refactor 12 files across 2,000 lines of code in 15 seconds. It takes a seasoned engineer at least 90 minutes of intense focus to properly read that diff. The review bottleneck has blown completely wide open.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cosmetic Perfection Masks Latent Disaster&lt;/strong&gt;: AI produces gorgeous code. The variable names are poetic, the formatting is spotless, and the docstrings are more descriptive than anything you’ve ever written. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When the human brain encounters a 2,000-line diff of aesthetically flawless code, cognitive fatigue sets in within 10 minutes. By line 400, your vigilance is dead. You scroll, nod, and hit &lt;strong&gt;"Approve"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You think you're standing guard as a gatekeeper. In reality, &lt;strong&gt;you're paying an extortionate cognitive tax just to purchase psychological comfort.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Great Rebuttal: "Compilers Don't Hallucinate, But AI Does!"
&lt;/h2&gt;

&lt;p&gt;Here comes the immediate objection—and it's a completely legitimate one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Wait a minute! Your Fortran analogy is fundamentally flawed. When developers abandoned manual assembly checks, it was because compilers are **deterministic&lt;/em&gt;&lt;em&gt;. A C compiler will never invent a nonexistent x86 instruction out of thin air. But LLMs are **probabilistic&lt;/em&gt;&lt;em&gt;—they hallucinate! If I don't read every line, how do I know the code won't blow up production?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bingo. This is the crux of the entire debate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yes, AI hallucinates. But relying on tired human eyeballs to catch those hallucinations in a 2,000-line diff is pure lunacy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why? Because in 2026, AI hallucinations are almost never obvious syntax errors.&lt;/p&gt;

&lt;p&gt;An AI doesn't write syntax that breaks the compiler. Instead, it introduces insidious, high-entropy bugs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It invents an optional parameter that sounds 100% plausible on an AWS SDK, but doesn't actually exist in that version.&lt;/li&gt;
&lt;li&gt;It silently omits an idempotent cleanup handler inside a retry loop that only fires after the 3rd network timeout.&lt;/li&gt;
&lt;li&gt;It writes a shared-memory concurrent routine that passes every naive unit test, but deadlocks under high-throughput race conditions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Be honest: Are you going to spot that subtle race condition by squinting at a green-and-red diff on GitHub at 11 PM? Or is an automated stress runner in an isolated sandbox going to catch it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer is obvious.&lt;/p&gt;

&lt;p&gt;When high-level languages replaced hand-written assembly, engineers didn't surrender to blind faith. They built &lt;strong&gt;type checkers, static analyzers, and compiler sanitizers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now that we are shifting to probabilistic AI generators, our defenses must evolve from &lt;em&gt;"human eyeballs scanning text"&lt;/em&gt; to &lt;strong&gt;"Rigid Upstream Contracts + Automated Machine Verification."&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The New Engineering Paradigm: The "Three Defenses"
&lt;/h2&gt;

&lt;p&gt;Elite teams who have stopped drowning in AI diffs have reorganized their workflow around a &lt;strong&gt;Three-Defense Framework&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Defense Layer&lt;/th&gt;
&lt;th&gt;Who / What Runs It&lt;/th&gt;
&lt;th&gt;Core Responsibility &amp;amp; Defensive Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;1. Upstream Legislation&lt;/strong&gt;&lt;br&gt;&lt;em&gt;(Architecture &amp;amp; Schema)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Human Architect + High-Reasoning Agent (e.g. agy / Claude Opus)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lock down strict interface contracts, database schemas, OpenAPI specs, and state transition invariants before a single line of business code is written. Never give the AI an unconstrained blank canvas.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;2. Midfield Pipeline&lt;/strong&gt;&lt;br&gt;&lt;em&gt;(Throughput &amp;amp; Anti-Corruption)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Fast Coder Agent + Strict Reviewer Agent + AST Refactoring Agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fast, high-throughput models (like DeepSeek Flash / Gemini Flash) implement the business logic. A detached reviewer agent audits against the contract (&lt;em&gt;review only, never edit&lt;/em&gt;). An advanced model cleans AST duplicates to prevent tech-debt rot.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;3. Downstream Verdict&lt;/strong&gt;&lt;br&gt;&lt;em&gt;(Empirical Proof &amp;amp; UX)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Independent Tester Agent in Sandbox + Real Human Product Sense&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sandbox agent boots clean environments, executes deterministic integration suites, fuzzing, and load tests. Humans step in as the final experiential authority to evaluate latency, tactile feel, and product delight.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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%2Fx2uddqie966txu96vf35.jpg" 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%2Fx2uddqie966txu96vf35.jpg" alt="The Three Defenses Architecture: Locking the ends and automating the middle" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 1: Anchor the Two Ends (Contracts Upstream, Evidence Downstream)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spend 80% of your time on the blueprint before coding&lt;/strong&gt;: Review data models, error boundaries, and API contracts with your AI. If the foundational schema is mathematically tight, the AI can code with its eyes closed and the house won’t collapse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judge by empirical runtime evidence, not code diffs&lt;/strong&gt;: Did the test coverage hit 95%? Did the integration suite pass under 1,000 virtual users on k6? Did the error rate stay at zero? &lt;strong&gt;Review the execution proof, not the syntax.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rule 2: Reclaim What Makes You Human
&lt;/h3&gt;

&lt;p&gt;Stop playing the role of an expensive human linter. Spend your precious biological brain cycles on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Untangling nuanced business logic and edge-case domain rules;&lt;/li&gt;
&lt;li&gt;Talking to real customers to unearth what they actually need;&lt;/li&gt;
&lt;li&gt;Actually running the compiled build, clicking through the app, and diagnosing clumsy UX friction that no LLM can feel.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. The Tooling Gap: Why Traditional IDEs and Isolated CLIs Fail Us
&lt;/h2&gt;

&lt;p&gt;If the "Three Defenses" paradigm makes so much sense, why are most developers still miserable?&lt;/p&gt;

&lt;p&gt;Because our developer tooling is trapped in the previous decade:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The IDE Monoculture Trap&lt;/strong&gt;: Editors like VS Code were built around the philosophy of &lt;em&gt;one human, one file, one cursor&lt;/em&gt;. When an AI refactors 40 files simultaneously, your IDE panics and dumps a massive two-column split diff on your screen, begging you to review line-by-line. The tool’s interaction model directly clashes with the model’s generation throughput.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Isolated CLI Bottleneck&lt;/strong&gt;: Running autonomous coding CLIs in separate terminal tabs quickly turns into a game of manual babysitting. You copy-paste API schemas between windows; long-running jobs silently freeze waiting for a &lt;code&gt;Proceed? [y/N]&lt;/code&gt; confirmation while you grab a coffee; and if a session crashes, all shared agent memory is gone.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This brings us to the missing link in the modern AI engineering stack: &lt;strong&gt;The pairing of advanced agentic CLI engines with a centralized, multi-agent terminal cockpit.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                       HUMAN ARCHITECT                       │
│           (Defines Contracts, Rules &amp;amp; UX Boundaries)        │
└──────────────────────────────┬──────────────────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────┐
│                 POLTER (Ghostty Multi-Agent Cockpit)        │
│  - Millisecond Quiescence Detection   - Persistent Task Bus │
│  - Autonomous Prompt Auto-Responder   - Shared Local State  │
├──────────────────────────────┬──────────────────────────────┤
│                              │                              │
│   Tab 1: Architect / Sup     │   Tab 2: agy (Antigravity)   │
│   (Claude Opus / Orchestrator)│   Autonomous Engine &amp;amp; Skills │
│   - Creates Task Cards       │   - Deep Codebase Invariants │
│   - Sets OpenAPI / Schemas   │   - Subagents &amp;amp; MCP Tools    │
│   - Delegates to Workers     │   - High-Throughput Coders   │
│                              │                              │
│   Tab 3: Sandbox / Stress    │   Tab 4: Cleaner / Sweeper   │
│   - Headless Docker Sandbox  │   - Cross-file AST Refactor  │
│   - k6 Load &amp;amp; Fuzz Testing   │   - Dead Code Elimination    │
│   - Emits Verified Evidence  │   - Anti-Corruption Layer    │
└─────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Heavy Hitter: &lt;code&gt;agy&lt;/code&gt; (Google Antigravity CLI)
&lt;/h3&gt;

&lt;p&gt;If you haven’t used &lt;strong&gt;&lt;code&gt;agy&lt;/code&gt; (Antigravity CLI)&lt;/strong&gt; yet, you are missing out on what a true agentic coding environment feels like. &lt;/p&gt;

&lt;p&gt;Unlike shallow autocomplete tools that merely guess the next five tokens, &lt;code&gt;agy&lt;/code&gt; was engineered from the ground up for high-leverage software engineering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rich Customization &amp;amp; Rules&lt;/strong&gt;: With hierarchical &lt;code&gt;.gemini/rules&lt;/code&gt; and dedicated agent roles, you can bake your architectural standards (e.g., &lt;em&gt;"Never mutate state directly," "All endpoints must validate Zod schemas"&lt;/em&gt;) straight into the agent’s subconscious.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Skills &amp;amp; MCP Tooling&lt;/strong&gt;: &lt;code&gt;agy&lt;/code&gt; dynamically activates specialized skills and hooks into local Model Context Protocol (MCP) servers, allowing it to inspect runtime databases, consult internal doc trees, and run diagnostics without context pollution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native Subagent Delegation&lt;/strong&gt;: Need to implement a new billing engine? &lt;code&gt;agy&lt;/code&gt; doesn’t dump everything into one giant prompt. It can spawn focused subagents (like a specialized research worker or an isolated refactoring unit), synthesize their outputs, and keep your core context clean.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Cockpit: Polter (Local Multi-Agent Orchestration)
&lt;/h3&gt;

&lt;p&gt;While &lt;code&gt;agy&lt;/code&gt; provides the cognitive horsepower and tool-use mastery inside a session, &lt;strong&gt;&lt;a href="https://github.com/Lugia123/polter" rel="noopener noreferrer"&gt;Polter&lt;/a&gt;&lt;/strong&gt; provides the system-level orchestration environment that ties everything together. Built on top of the ultra-fast Ghostty terminal, Polter turns separate terminal tabs into a synchronized, autonomous engineering floor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Supervisor Mode &amp;amp; Externalized Task State&lt;/strong&gt;: In Polter, an orchestrator terminal (running &lt;code&gt;become_supervisor&lt;/code&gt;) ingests human requirements, writes immutable contracts, and uses &lt;code&gt;task_create&lt;/code&gt; to populate a persistent, local task board. Even if your machine reboots, every worker’s status (&lt;code&gt;open&lt;/code&gt;, &lt;code&gt;working&lt;/code&gt;, &lt;code&gt;closed&lt;/code&gt;) is fully preserved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quiescence Detection &amp;amp; Smart Auto-Answering&lt;/strong&gt;: The biggest killer of automated agent workflows is the silent prompt freeze. If an agent runs an &lt;code&gt;npm install&lt;/code&gt; or creates a directory that prompts &lt;code&gt;[Y/n]&lt;/code&gt;, traditional setups wait forever. Polter monitors screen quiescence down to the millisecond. If a terminal idles on a non-destructive prompt, the supervisor reads the screen with &lt;code&gt;terminal_read&lt;/code&gt; and safely dispatches &lt;code&gt;terminal_answer_prompt&lt;/code&gt; to unblock the pipeline. Human intervention is only requested for genuinely risky actions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decoupled Asynchronous Local Bus&lt;/strong&gt;: Instead of piping everything through a fragile cloud server, worker terminals communicate through local file-backed group channels (&lt;code&gt;group_post&lt;/code&gt; and &lt;code&gt;group_read&lt;/code&gt;). An &lt;code&gt;agy&lt;/code&gt; agent completes a module, posts the build receipt to the channel, and immediately triggers an isolated testing terminal to run the validation suite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evidence-Driven Handoff&lt;/strong&gt;: When &lt;code&gt;agy&lt;/code&gt; finishes a feature under Polter’s watch, you don’t get a 2,000-line diff to eyeball. You get a tidy summary from the supervisor:
&amp;gt; &lt;em&gt;"Feature implemented by agy against OpenAPI spec v2.1. 3 sub-tasks closed. Sandbox integration test passed (52/52 assertions). Zero regressions detected. Here is the live staging URL to try it out."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is what modern software engineering looks like.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Conclusion: From Code Reviewer to Systems Designer
&lt;/h2&gt;

&lt;p&gt;Every major transition in software history has met resistance because it forced developers to redefine their self-worth.&lt;/p&gt;

&lt;p&gt;In 1957, Fortran didn’t eliminate programmers—it liberated them from allocating registers and calculating memory byte offsets, sparking the software revolution that created the modern world.&lt;/p&gt;

&lt;p&gt;In 2026, generative AI and tools like &lt;code&gt;agy&lt;/code&gt; have driven the marginal cost of syntax generation to zero. In response, &lt;strong&gt;the marginal return of reviewing raw syntax line-by-line has collapsed into negative territory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The essence of software engineering hasn’t died. Only the interface has changed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stop being a human spell-checker; become an architectural legislator.&lt;/strong&gt; Your value is in defining razor-sharp schemas, invariant rules, and error budgets before the code is generated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop eyeballing diffs; demand empirical, automated proof.&lt;/strong&gt; Let deterministic compilers, strict type systems, and headless sandbox runners catch hallucinations. Trust machine evidence, not your late-night eyesight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Save your human intuition for the product itself.&lt;/strong&gt; When the terminals, agents, and cockpits handle the heavy lifting, you can finally focus on what software was always meant to do: solve complex human problems with clarity, speed, and elegance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Step away from that 2,000-line diff. Put on your architect hat. The new abstraction layer is already here.&lt;/p&gt;




&lt;h3&gt;
  
  
  Resources &amp;amp; Open Source Projects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;strong&gt;Polter Terminal Workbench&lt;/strong&gt;: &lt;a href="https://github.com/Lugia123/polter" rel="noopener noreferrer"&gt;https://github.com/Lugia123/polter&lt;/a&gt; — &lt;em&gt;A 100% local, multi-agent terminal cockpit built on Ghostty with supervisor scheduling, quiescence detection, and automated task persistence.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Google Antigravity (&lt;code&gt;agy&lt;/code&gt;) Ecosystem&lt;/strong&gt;: Leverage custom skills, MCP tools, and autonomous subagent workflows to power your development engine.&lt;/li&gt;
&lt;li&gt;💬 &lt;em&gt;How is your team dealing with massive AI pull requests? Are you still reading every diff, or have you moved to contract-driven verification? Let’s argue in the comments below.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Every Test Passed. Then the UI Got Thrown Out.</title>
      <dc:creator>Lugiax</dc:creator>
      <pubDate>Wed, 21 Oct 2026 15:53:55 +0000</pubDate>
      <link>https://dev.to/lugia123/every-test-passed-then-the-ui-got-thrown-out-3pln</link>
      <guid>https://dev.to/lugia123/every-test-passed-then-the-ui-got-thrown-out-3pln</guid>
      <description>&lt;p&gt;At 1:31 AM, the automated checklist reached its final item.&lt;/p&gt;

&lt;p&gt;Eight checks: seven passed, one was marked "record current state," and not a single check was red. By every test report, the feature was done and ready to ship.&lt;/p&gt;

&lt;p&gt;Then the user stopped everything.&lt;/p&gt;

&lt;p&gt;The verdict was one short sentence that no test suite could argue with: the UI looks bad, redo all of it.&lt;/p&gt;

&lt;p&gt;Most developers have been here. The pipeline is green, you feel the relief, and then a person looks at the thing and it feels wrong. The logic is sound. The product still isn't right.&lt;/p&gt;

&lt;p&gt;The feature was a native screenshot tool for an open-source terminal app. Press a shortcut, freeze the screen, drag out a region, and draw on top of it. AI agents wrote most of the code; human developers set the direction and made the hard calls.&lt;/p&gt;

&lt;p&gt;From the first line of code to the final UI took 10 hours 22 minutes and 27 commits.&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%2Fg0ry2wv71gt7xb5u6ph9.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%2Fg0ry2wv71gt7xb5u6ph9.png" alt="Timeline of the session: 10 hours 22 minutes, 27 commits, from 16:25 to 02:47 the next day" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Along the way, we ran into three nasty bugs on real hardware that the test suite never caught. Those bugs make up the first half of this story.&lt;/p&gt;

&lt;p&gt;The second half is about what happened after that "redo all of it" order, and how we turned a vague complaint into hard numbers.&lt;/p&gt;

&lt;p&gt;It all started with an architectural choice that seemed sensible at first, until we threw the whole thing away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we threw away the macOS code to mirror Windows function by function
&lt;/h2&gt;

&lt;p&gt;The tool had to ship on both Windows and macOS.&lt;/p&gt;

&lt;p&gt;My first instinct was that each platform could do its own thing internally, as long as the visible features matched.&lt;/p&gt;

&lt;p&gt;That idea didn't last long. Windows got the first build, and then macOS followed. A few hours later, the macOS code was thrown away. It was rewritten from scratch to mirror the Windows version function by function.&lt;/p&gt;

&lt;p&gt;The spec said the two platforms had to behave the same, item by item. The only allowed difference was the modifier key: Command on macOS where Windows uses the Windows key. Both sides also had to run against the exact same test data and produce the exact same expected outputs.&lt;/p&gt;

&lt;p&gt;The dev log puts the reason plainly (translated from Chinese): we want both platforms to produce the same exact value, not two values that are close.&lt;/p&gt;

&lt;p&gt;Think of two cooks making the same dish. If each works from memory, you get two meals that taste "about the same." If both follow one recipe and weigh every ingredient on a scale, you get the exact same dish.&lt;/p&gt;

&lt;p&gt;None of this had run on a physical machine yet. One of the early commit messages says so (again translated): "No human has pressed confirm on this version yet."&lt;/p&gt;

&lt;p&gt;The first run on a real Windows machine broke the undo shortcut immediately.&lt;/p&gt;

&lt;p&gt;The undo button on the screen worked fine, but the keyboard shortcut did nothing. The code checked the keyboard state at the exact moment the event got handled. When you tap a shortcut quickly, your fingers are already off the keys by the time the handler runs.&lt;/p&gt;

&lt;p&gt;That was the easy one to fix. The next bug on Windows froze the whole app.&lt;/p&gt;

&lt;h2&gt;
  
  
  A thin white edge that froze the app in an endless loop
&lt;/h2&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%2Fsw2ubb3ipi0ex87cetdw.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%2Fsw2ubb3ipi0ex87cetdw.png" alt="The annotation text box sitting over the toolbar, with a loading spinner: the app has hung" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A screenshot tool needs text annotations. That means a floating text box sits next to a toolbar with pens, arrows, and other tools.&lt;/p&gt;

&lt;p&gt;In some screen layouts, the text box ended up sitting right on top of the toolbar. To keep the toolbar buttons clickable, we cut a transparent hole in the text box where they overlapped.&lt;/p&gt;

&lt;p&gt;Clicks worked again, but the cutout left a thin white edge behind. It was the text box's own white background bleeding through.&lt;/p&gt;

&lt;p&gt;The obvious fix seemed to be a quick patch. Every time the text box moved, we forced the toolbar to repaint (redraw its pixels on screen) over the overlapping area to cover the white edge.&lt;/p&gt;

&lt;p&gt;Instead, the app froze.&lt;/p&gt;

&lt;p&gt;On a physical Windows machine, opening the text box sent CPU usage spiking. The program spun in place and locked up. Four tries, four hangs.&lt;/p&gt;

&lt;p&gt;The cause was hidden deep inside how Windows draws native controls.&lt;/p&gt;

&lt;p&gt;The native text box keeps an old behavior that lets a control paint outside its own bounds. That white edge was the control painting past its own border. Each forced repaint woke that out-of-bounds painting up again, which triggered another repaint request, spinning forever in an infinite loop.&lt;/p&gt;

&lt;p&gt;The fix wasn't another patch. We swapped the native text box for one with that out-of-bounds painting turned off.&lt;/p&gt;

&lt;p&gt;Once the control could no longer paint past its own edge, the white strip was gone for good.&lt;/p&gt;

&lt;p&gt;Before you cover one patch with another, find the control that is drawing where it shouldn't be.&lt;/p&gt;

&lt;p&gt;That was Windows. On macOS, a different bug was waiting in the same text box.&lt;/p&gt;

&lt;h2&gt;
  
  
  The macOS text box that typed "n你好" instead of "你好"
&lt;/h2&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%2Fw5pgkpztgfc3qc1ih4jg.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%2Fw5pgkpztgfc3qc1ih4jg.png" alt="Keys n-i-h-a-o and space, and the text field showing " width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next bug showed up on macOS.&lt;/p&gt;

&lt;p&gt;In the screenshot text box, using the built-in Pinyin input method, you type &lt;code&gt;n-i-h-a-o&lt;/code&gt; and press space to confirm. That should produce 你好 ("hello").&lt;/p&gt;

&lt;p&gt;What actually showed up was "n你好". The first letter was stuck in front of the Chinese characters.&lt;/p&gt;

&lt;p&gt;Here's some background if you have never worked with an IME (an Input Method Editor, the system tool used to type characters in languages like Chinese or Japanese). While you type Pinyin letters, they sit in a temporary composition buffer. macOS calls this active state marked text. Only when you confirm your selection does that buffer turn into real characters and commit to the field.&lt;/p&gt;

&lt;p&gt;The bug came from an auto-grow feature. The text box starts one line tall and gets taller as you type.&lt;/p&gt;

&lt;p&gt;The first time the box grew taller, the operating system switched the text layout engine underneath. That switch cleared the marked text state. Because the buffer was suddenly wiped out, the system treated the first letter, &lt;code&gt;n&lt;/code&gt;, as already-committed text.&lt;/p&gt;

&lt;p&gt;The dev log pinned it down (translated): "Didn't happen in earlier builds. Regression from the dynamic height change."&lt;/p&gt;

&lt;p&gt;A regression is when previously working code breaks because of a new change.&lt;/p&gt;

&lt;p&gt;The fix was to lock the text box to one layout engine from the moment it was created, and never let it switch. After that, we tested every font size on a real Mac, and 你好 came out clean.&lt;/p&gt;

&lt;p&gt;The interesting part is that this bug never showed up in our automated tests. They run without real window management, and that's where the bug lives.&lt;/p&gt;

&lt;p&gt;Anything that touches IME state, marked text, or window focus must be typed into on a physical machine.&lt;/p&gt;

&lt;p&gt;Text input was fixed. The scrolling capture was next, and it had its own trap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the scrolling screenshot refused to move past the first screen
&lt;/h2&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%2Fnw0nw91ptdgc4dajtimp.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%2Fnw0nw91ptdgc4dajtimp.png" alt="Two frames before and after scrolling three lines: the window border column on the right never moves, and the scrollbar thumb shifts a little" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The third problem was the scrolling screenshot, also called a long screenshot.&lt;/p&gt;

&lt;p&gt;The concept is straightforward. The user scrolls down, the capture engine grabs frames quickly, compares each new frame to the last one to find where they overlap, and appends the newly revealed part to the bottom.&lt;/p&gt;

&lt;p&gt;To find the overlap, we used a strict pixel diff (a row-by-row pixel comparison). If row X of the previous frame exactly matches row Y of the current one, the algorithm knows how far the page moved.&lt;/p&gt;

&lt;p&gt;On a real machine, no matter how far you scrolled, the output image stayed stuck at one screen tall. Not a single new frame got merged.&lt;/p&gt;

&lt;p&gt;The culprit was a column of pixels that never moved at all: the window border.&lt;/p&gt;

&lt;p&gt;The page content scrolled, but the window border at the edge of the selected region stayed put. Every row in the comparison had a few border pixels that could never match. In a strict comparison, one mismatched pixel rejects the entire row. Every row got rejected, so the engine concluded there was no overlap anywhere.&lt;/p&gt;

&lt;p&gt;The fix follows from that: before comparing frames, drop the pixel columns that stay completely still from top to bottom, so they don't count toward the match.&lt;/p&gt;

&lt;p&gt;There's a trap in that rule. "Still" must mean the column is exactly identical all the way down, not just mostly identical. Take line numbers in a code editor. They look almost the same from row to row, but their small shifts are the best signal you have for tracking how far the page moved.&lt;/p&gt;

&lt;p&gt;With the border handled, the scrollbar broke the algorithm next. The scrollbar thumb doesn't scroll with the page, and it doesn't stay still either. It moves a little, at its own separate ratio.&lt;/p&gt;

&lt;p&gt;So the engine received a second rule. If a pixel column changes in at most two segments, and the changed part is less than half its height, it is treated as background noise and left out of the comparison.&lt;/p&gt;

&lt;p&gt;We also added a safety rule for failure. If the user scrolls so fast that frames get dropped, the engine throws away the broken frame and displays a "slow down" message. It never forces a stitch.&lt;/p&gt;

&lt;p&gt;Before you ask an algorithm to compare two things, cut out everything that shouldn't be part of the comparison.&lt;/p&gt;

&lt;p&gt;That should have been the end of the night. It wasn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turning "it looks bad" into hard pixel measurements
&lt;/h2&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%2Faclnobgndmn16ea9rc1u.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%2Faclnobgndmn16ea9rc1u.png" alt="Bar chart of filled pixels per toolbar icon: mosaic 732, undo 88, a ratio of 8.3x" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With those three bugs resolved, testing on real hardware went green. That brought us right back to 1:31 AM.&lt;/p&gt;

&lt;p&gt;All 8 checks passed. Buttons responded, text input worked, and long screenshots stitched cleanly. QA had nothing left to mark as failed.&lt;/p&gt;

&lt;p&gt;Then came the user review. The complaints were clear:&lt;/p&gt;

&lt;p&gt;The icons didn't feel balanced in visual weight. The gray plate behind the selected tool looked cheap. The dots used to pick the font size didn't make sense. And the opaque text box covered what was underneath it.&lt;/p&gt;

&lt;p&gt;Editing code against feedback like that is guesswork.&lt;/p&gt;

&lt;p&gt;So we stopped writing code and started measuring pixels.&lt;/p&gt;

&lt;p&gt;We used the app's own rendering code to draw each toolbar icon on its own, and we counted how many pixels it filled.&lt;/p&gt;

&lt;p&gt;The hard numbers explained the imbalance immediately.&lt;/p&gt;

&lt;p&gt;The lightest icon (undo) and the heaviest icon (mosaic) differed in filled area by 8.3x. Picture a shot put and a balloon sitting side by side in the same toolbar.&lt;/p&gt;

&lt;p&gt;The shapes were misaligned as well. The long-screenshot icon was tall and thin like a pole, sticking up above the baseline. The arrow in the selection tool wasn't centered in its 16x16 grid; it leaned noticeably to the left.&lt;/p&gt;

&lt;p&gt;The worst find was where the graphics came from. 5 icons were not drawn from vector paths at all. They were plain characters pulled from the host operating system's fonts. Windows and macOS ship different system fonts, so those 5 icons looked visibly different on the two platforms.&lt;/p&gt;

&lt;p&gt;"It looks bad" was no longer a matter of opinion. It was now a table of pixel measurements. That table became the acceptance criteria for the UI rework.&lt;/p&gt;

&lt;p&gt;When someone says something looks wrong and you can't argue with it, the first step is to find a way to measure it.&lt;/p&gt;

&lt;p&gt;We had the data. But before we touched any code, we changed how we worked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Locking in the mockup before writing a single line of native code
&lt;/h2&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%2Fwhhu5yaoknsn0cmweqb3.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%2Fwhhu5yaoknsn0cmweqb3.png" alt="The final toolbar mockup, with the selected tool marked by a thin blue ring" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time, no AI was allowed to touch the code.&lt;/p&gt;

&lt;p&gt;We had already seen what happens otherwise. You build the UI in code, compile it, and show it to the user. If the visual direction is wrong, all the cross-platform work gets thrown out.&lt;/p&gt;

&lt;p&gt;So we went mockup-first.&lt;/p&gt;

&lt;p&gt;We built high-fidelity mockups using web technologies. A browser mockup isn't the native code that ships to users, but you can iterate on it more than ten times faster than on compiled code.&lt;/p&gt;

&lt;p&gt;From the "redo all of it" order to the new UI spec being committed took 76 minutes. In that time, the mockup went through three major versions.&lt;/p&gt;

&lt;p&gt;Each small request got settled directly inside the mockup: hover feedback, replacing the confusing font-size dots with a small and a large letter "T," and switching a solid border to a dashed one so it blocked less of the view.&lt;/p&gt;

&lt;p&gt;Making those changes in native code would have meant editing and recompiling both platforms dozens of times. In the mockup, it was just dragging elements and changing values.&lt;/p&gt;

&lt;p&gt;Any disagreement about looks that can be settled in a mockup should never make it into the code.&lt;/p&gt;

&lt;p&gt;The visual design was locked in. Now we had to build it in native code without letting the two platforms drift apart by a single pixel.&lt;/p&gt;

&lt;h2&gt;
  
  
  One data file, two platforms, zero pixel difference
&lt;/h2&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%2Ffa0vwjp0xi30kpr3nu0z.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%2Ffa0vwjp0xi30kpr3nu0z.png" alt="One JSON data file feeding generated Rust constants for Windows and Swift constants for macOS" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the design settled, the engineering question was how to guarantee that the two platforms could never drift apart, even by a single pixel.&lt;/p&gt;

&lt;p&gt;The lesson from the old version was clear. Each platform had its own separate implementation, and 5 icons ended up looking different on each.&lt;/p&gt;

&lt;p&gt;This time, we established a single source of truth.&lt;/p&gt;

&lt;p&gt;A single source of truth means one file that every platform reads from. Every UI parameter (color values, spacing, and Bézier control points) went into one standalone data file.&lt;/p&gt;

&lt;p&gt;The Windows and macOS UI code was no longer written by the AI agents. Instead, a custom script reads that data file and generates the UI code for each platform automatically.&lt;/p&gt;

&lt;p&gt;It works like casting parts from a single mold: parts from the same mold cannot drift past tolerance.&lt;/p&gt;

&lt;p&gt;Rendering received the exact same treatment.&lt;/p&gt;

&lt;p&gt;The native drawing APIs on Windows and macOS handle anti-aliasing slightly differently. Anti-aliasing is how graphics systems smooth the jagged edges of lines. Because the two systems drew lines differently, we stopped using the built-in line drawing and ran the same basic rendering code on both platforms.&lt;/p&gt;

&lt;p&gt;To check our work, we pulled the outlines of all 60 icons as rendered on each platform and compared them pixel by pixel.&lt;/p&gt;

&lt;p&gt;They matched exactly, with zero pixel difference.&lt;/p&gt;

&lt;p&gt;The code was unified, and the icons were identical. Which brings us back to what that green test suite actually meant.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a green test suite can and cannot promise
&lt;/h2&gt;

&lt;p&gt;Boil those 10 hours 22 minutes down, and you get a clear lesson: automated tests are very good at catching logic bugs, but they are blind to how an app feels to use. A lot of what makes software feel well made sits outside the green checkmarks.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What automated tests can promise&lt;/th&gt;
&lt;th&gt;What a human still has to check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline is green, no errors&lt;/td&gt;
&lt;td&gt;Is a test case missing? Did a real problem quietly get downgraded to "record current state"?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unit tests pass 100%&lt;/td&gt;
&lt;td&gt;Has it run on a physical machine? Has a person's hand gone through the interaction?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The visual glitch (white edge) is covered up in code&lt;/td&gt;
&lt;td&gt;Was the underlying cause removed, or just covered with another patch?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frame comparison failed, logic stopped&lt;/td&gt;
&lt;td&gt;Did the algorithm drop the noise that never belonged in the comparison?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The feature works end to end&lt;/td&gt;
&lt;td&gt;Does it look and feel right? Was there a high-fidelity review before coding?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Both platforms are done&lt;/td&gt;
&lt;td&gt;Were both generated from the same data, or did each side settle on its own version?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Think back to 1:31 AM.&lt;/p&gt;

&lt;p&gt;The all-green checklist didn't lie. It checked everything it was built to check. It just had no item for "does this look good."&lt;/p&gt;

&lt;p&gt;Next time someone tells you all tests pass, ask one more question: beyond the code being correct, who decided how it should look and feel, and at what point?&lt;/p&gt;

&lt;p&gt;The screenshot tool, new toolbar included, has shipped in Polter, a terminal for macOS and Windows built on Ghostty's rendering: &lt;a href="https://github.com/Lugia123/polter" rel="noopener noreferrer"&gt;https://github.com/Lugia123/polter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>ui</category>
      <category>crossplatform</category>
      <category>ai</category>
    </item>
    <item>
      <title>Save Your Whole Terminal Workspace as a Project in Polter</title>
      <dc:creator>Lugiax</dc:creator>
      <pubDate>Tue, 20 Oct 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/lugia123/save-your-whole-terminal-workspace-as-a-project-in-polter-2l2a</link>
      <guid>https://dev.to/lugia123/save-your-whole-terminal-workspace-as-a-project-in-polter-2l2a</guid>
      <description>&lt;p&gt;You have the same three tabs open every day: a dev server, &lt;code&gt;tail -f&lt;/code&gt; on a log, and a pane for git and vim. Then you restart. You &lt;code&gt;cd&lt;/code&gt; three times, retype three commands, and whatever error you were reading is gone.&lt;/p&gt;

&lt;p&gt;Polter is a terminal for macOS and Windows built on Ghostty's rendering. Its main feature is projects: workspaces you save and load back later. This post follows the video chapter by chapter.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/fOjuj1HZXTM" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;A quick note on the base: Polter uses Ghostty's rendering, VT parsing, and fonts (MIT). It is not an official Ghostty project and is not affiliated with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Set up a normal workday
&lt;/h2&gt;

&lt;p&gt;The demo project is called &lt;code&gt;shop-web&lt;/code&gt;. It has three tabs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tab 1, split in two with ⌘D. Left: &lt;code&gt;python3 -m http.server 8123&lt;/code&gt;. Right: &lt;code&gt;tail -f logs/app.log&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tab 2: &lt;code&gt;git log --oneline -20&lt;/code&gt;, then a quick edit in &lt;code&gt;vim README.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tab 3: a few loose commands such as &lt;code&gt;ls -la&lt;/code&gt; and &lt;code&gt;du -sh *&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Save it as a project
&lt;/h2&gt;

&lt;p&gt;Right-click a tab and choose &lt;strong&gt;Save as Project…&lt;/strong&gt; (it is also in the &lt;strong&gt;Project&lt;/strong&gt; menu). The dialog lists the window's tabs. Only the current one is ticked, so tick all three, type a name (&lt;code&gt;shop-web&lt;/code&gt;), and confirm.&lt;/p&gt;

&lt;p&gt;You only do this once. Polter writes layout changes back to the project on its own. If you drag a split divider, the new ratio is saved without another click.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Quit, reopen, load
&lt;/h2&gt;

&lt;p&gt;Press ⌘Q. If a process is still running, Polter asks first; click Terminate. Reopen the app and you get a single empty window. Choose &lt;strong&gt;Project → Load Project…&lt;/strong&gt; and pick &lt;code&gt;shop-web&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You get your three tabs back, along with the split ratio, every pane in its own directory, and the old output. A dim divider line separates the last session from the new one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;── Above this line: history restored from the previous session ──
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below it sits a fresh prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. What does not come back
&lt;/h2&gt;

&lt;p&gt;This part matters more than the demo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Processes.&lt;/strong&gt; The server in the left pane is not running. The pane shows the old output and a new shell. Your command history did come along: press Up, then Enter, and the server is back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full-screen programs.&lt;/strong&gt; The tab where you used vim shows what was printed before vim opened, not vim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kitty graphics&lt;/strong&gt; come back as blank space.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need processes to survive, that is tmux's job. tmux keeps processes alive when you close a window, though its server also dies on reboot. You can run tmux inside Polter.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Crashes and power cuts
&lt;/h2&gt;

&lt;p&gt;Scrollback is written to disk while panes run: every 5 seconds by default, new lines only. In the worst case, you lose about 5 seconds of output. Each pane keeps 10 MB of scrollback by default, which is about 120,000 lines of plain text. When it fills, the oldest lines go first.&lt;/p&gt;

&lt;p&gt;The two settings are &lt;code&gt;project-scrollback-autosave-interval&lt;/code&gt; and &lt;code&gt;project-scrollback-limit-bytes&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. The Settings window and your config file
&lt;/h2&gt;

&lt;p&gt;Press ⌘, to open Settings. Changing the font size updates the terminal immediately, with no save button.&lt;/p&gt;

&lt;p&gt;The window edits your plain-text config. On macOS the file is at &lt;code&gt;~/Library/Application Support/com.lugia.polter/config.polter&lt;/code&gt;. If a setting is already in the file, such as &lt;code&gt;font-size = 20&lt;/code&gt;, Polter replaces that line in place. If it is not there, Polter appends it at the end in a block marked as written by the Settings window. A backup (&lt;code&gt;config.polter.polter-bak&lt;/code&gt;) is made before the first write after each launch.&lt;/p&gt;

&lt;p&gt;You can still edit the file by hand. Save it, press ⇧⌘, to reload the config, and the Settings window shows the new value. The window does not watch the file, so it will not update without that reload.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. The MCP interface
&lt;/h2&gt;

&lt;p&gt;The last chapter is for tinkerers. Polter ships an MCP interface: other programs can list your terminals, read a screen, and type for you. The config line is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"polter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"+mcp"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the video I use the generic MCP Inspector to call &lt;code&gt;terminal_list&lt;/code&gt;, &lt;code&gt;terminal_read&lt;/code&gt; and &lt;code&gt;terminal_send&lt;/code&gt;. It has guards. If you typed in a pane in the last ten seconds, &lt;code&gt;terminal_send&lt;/code&gt; is refused with &lt;code&gt;UserPresent&lt;/code&gt;. If there is half a command on the line, it is refused with &lt;code&gt;DraftInLine&lt;/code&gt;. Setting &lt;code&gt;poltergeist-mcp = false&lt;/code&gt; turns the interface off. I have only exercised it through the Inspector.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Windows and download
&lt;/h2&gt;

&lt;p&gt;The same project model runs on Windows; the video shows a short clip. Packages are on the releases page for macOS 13+ and Windows 10+. There is no Linux installer yet, so on Linux you build from source.&lt;/p&gt;

&lt;p&gt;Download: &lt;a href="https://github.com/Lugia123/polter/releases/latest" rel="noopener noreferrer"&gt;https://github.com/Lugia123/polter/releases/latest&lt;/a&gt;&lt;br&gt;
Source (MIT): &lt;a href="https://github.com/Lugia123/polter" rel="noopener noreferrer"&gt;https://github.com/Lugia123/polter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try it, save a project, quit, reopen, and look for the divider line. I would like to hear what you would want saved that is not.&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>productivity</category>
      <category>macos</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I Built a Windows Version of Ghostty in 3 Days with AI</title>
      <dc:creator>Lugiax</dc:creator>
      <pubDate>Wed, 23 Sep 2026 18:41:04 +0000</pubDate>
      <link>https://dev.to/lugia123/how-i-built-a-windows-version-of-ghostty-in-3-days-with-ai-1d2j</link>
      <guid>https://dev.to/lugia123/how-i-built-a-windows-version-of-ghostty-in-3-days-with-ai-1d2j</guid>
      <description>&lt;h2&gt;
  
  
  Main Text
&lt;/h2&gt;

&lt;p&gt;Ghostty is a terminal tool. It was made by Mitchell Hashimoto, the same person who made Vagrant and Terraform. It uses Zig language at its core. On Mac, it uses Swift. On Linux, it uses GTK. But there is no Windows version.&lt;/p&gt;

&lt;p&gt;I made a copy (forked it), and three days later, the Windows version was running. The first change (commit) was on September 1st at 2:30 AM. I released the first version on September 4th. The Windows part has 45 files and 48,000 lines of Rust code. I did not write a single line of code myself. There were 246 changes, and Claude (an AI) helped with every single one.&lt;/p&gt;

&lt;p&gt;This post is about what I did during those three days.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Tool I Used Is the Thing I Am Building
&lt;/h3&gt;

&lt;p&gt;First, I need to explain why I copied this project. It wasn't just to get Ghostty on Windows. I did it to build an AI CLI (command-line) manager. This means using tools like Claude Code to manage and automate coding.&lt;/p&gt;

&lt;p&gt;The idea is simple. You pick one AI to be the "manager." This manager can see when other AI workers are stuck. It can read their screens, type for them, open new windows, and bring everyone into a group chat. There is also a task board to help them work together.&lt;/p&gt;

&lt;p&gt;The Windows version was built using this exact system. I used my tool and AI to build the tool itself.&lt;/p&gt;




&lt;h3&gt;
  
  
  Getting to Work
&lt;/h3&gt;

&lt;p&gt;There was one AI manager and three or four AI workers. Each worker was a separate Claude session. The manager made a group chat, broke the work into smaller tasks, and put them on the board. Then, it gave tasks to the workers one by one. My job was to set the direction, make big choices, and watch them work.&lt;/p&gt;

&lt;p&gt;I made three rules for the AI:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Workers cannot touch git (the saving system).&lt;/strong&gt; They could not commit or add files. Only the manager could do that. Why? Once, the manager told me two workers didn't have conflicting code. It heard this from one of the workers. But another worker said there &lt;em&gt;was&lt;/em&gt; a conflict! So I changed the rule: if you change something, you just say so. The manager must check for conflicts itself by looking at the files directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Two people cannot build the code at the same time.&lt;/strong&gt; The Zig builder deletes some files before remaking them. If someone else tries to build at the exact same time, it crashes. The first two times this happened, I wrongly thought the code was broken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Do not touch programs you didn't start.&lt;/strong&gt; This sounds obvious. But sometimes, when the AI tries to "clean up," it will close a window that you are still using!&lt;/p&gt;




&lt;h3&gt;
  
  
  Why I Chose Rust
&lt;/h3&gt;

&lt;p&gt;I didn't let the AI choose the coding language for the outside layer (the shell). That choice changes everything.&lt;/p&gt;

&lt;p&gt;First, I ruled out the Linux Zig code. It has 23,000 lines, which sounds helpful. But it is all GTK (a Linux window tool). The windows, tabs, and typing all use GTK. If I moved that to Windows, none of it would work.&lt;/p&gt;

&lt;p&gt;The hardest part was actually the typing system (input method).&lt;/p&gt;

&lt;p&gt;Windows uses a typing system called TSF, built with something called COM. C++ and C# can use it easily. But Zig does not know how to use it. If you make one tiny mistake setting it up in Zig, the whole program crashes. Typing is the hardest part of a Windows terminal. And Chinese users need it within 10 seconds of starting the app.&lt;/p&gt;

&lt;p&gt;Mac and Linux have easy ways to connect to their typing systems. Zig handles them well. But Windows uses COM.&lt;/p&gt;

&lt;p&gt;Rust has official tools from Microsoft that support COM perfectly. By choosing Rust, all the typing code stays in Rust. Zig never has to touch COM.&lt;/p&gt;

&lt;p&gt;In the end, I only changed about 20 lines of Zig code. The system info was squished into a small box. I just added a line for Windows, and that was it. Rust did all the rest of the work. Plus, the Mac version already did this, so we had an answer key to look at.&lt;/p&gt;




&lt;h3&gt;
  
  
  Tackling the Hardest Part First
&lt;/h3&gt;

&lt;p&gt;Normally, you make the window show up first. Seeing it makes you feel good. But I told the AI to fix the typing system first.&lt;/p&gt;

&lt;p&gt;This was the only part where I couldn't guess how hard it would be just by looking. If it was ten times harder than I thought, I needed to know before writing 20,000 lines of code.&lt;/p&gt;

&lt;p&gt;It went very well. The typing code was over 400 lines. The very first time we built it and moved it to Windows, it worked! I typed &lt;code&gt;n i h a o&lt;/code&gt;, the word box popped up, I pressed 1, and "你好" (hello) appeared.&lt;/p&gt;

&lt;p&gt;I still remember one line from the log file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SetText 0..2 &amp;lt;- "你"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means "Replace spaces 0 to 2 with '你'". In computer memory, this is one letter. But on the screen, it takes up two spaces. If the computer thought it was 1 space, the word box would be in the wrong place. This only happens with Chinese, Japanese, and Korean text. English would look perfectly fine. These bugs are very hard to find.&lt;/p&gt;

&lt;p&gt;The best part is that the AI didn't just guess the number "2". It asked the core program for the real size using the correct size chart. Seeing this made me trust this way of working.&lt;/p&gt;




&lt;h3&gt;
  
  
  Fixing the Black Screen Bug
&lt;/h3&gt;

&lt;p&gt;We had a window, and typing worked. But when we connected the core program, the screen was completely black.&lt;/p&gt;

&lt;p&gt;It didn't crash. It was just quietly black. Everything succeeded, and the window was getting messages to "redraw," but there were zero pixels on the screen.&lt;/p&gt;

&lt;p&gt;Later, I found a pattern. If I made a small window and then dragged it bigger, it was black. But if I started it at the final big size right away, the picture showed up.&lt;/p&gt;

&lt;p&gt;I checked the logs and measured it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Painted area = 1000x670      &amp;lt;- This was the size when the window was first made.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if I made the window bigger six times, this number never changed.&lt;/p&gt;

&lt;p&gt;But the terminal itself was awake. If I typed a command in full screen to check the size, it said 143 columns and 41 rows. That perfectly matched the full screen size. The core program knew the right size.&lt;/p&gt;

&lt;p&gt;We kept checking every step. The numbers were right at every step. Two AI workers wrote tests, and both failed. The screen was still black.&lt;/p&gt;

&lt;p&gt;Then we tried a new way. I told the AI to stop reading logs. Instead, it took a screenshot and used a drawing tool to find exactly where the black and white met.&lt;/p&gt;

&lt;p&gt;The line was exactly at 1000. Everything was the right size, but only a rectangle the size of the &lt;em&gt;old&lt;/em&gt; window was being drawn on the screen.&lt;/p&gt;

&lt;p&gt;I moved the log to the very last step, where the picture is actually put on the screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target=1240x790  Image area=1240x790  Canvas=1240x790
Drawable area=(0,0,1000,670)          &amp;lt;- It died right here.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first three numbers updated, but the last one was stuck at the old size.&lt;/p&gt;

&lt;p&gt;I looked at the code and found the function that sets this area. I searched to see who used it. Zero results.&lt;/p&gt;

&lt;p&gt;This "drawable area" was only set one time, right when the window was created. After that, no one ever updated it.&lt;/p&gt;

&lt;p&gt;Why didn't Linux have this problem? I looked at the Linux code. GTK kindly resets this area for us every time the window gets bigger. Windows doesn't do that. It gives you a blank slate.&lt;/p&gt;

&lt;p&gt;The worst part was that there was a note in the code about this! It said, "No one does this on a bare window." The people who read that note didn't realize it was a bug.&lt;/p&gt;

&lt;p&gt;Looking back, starting with a big window only worked because the one-time setup matched the final size. The bug was always there; it just hid whenever the window was resized.&lt;/p&gt;




&lt;h3&gt;
  
  
  Don't Trust the AI When It Says "Everything is Green"
&lt;/h3&gt;

&lt;p&gt;The hard part about AI coding isn't getting it to write. It's that the AI will confidently tell you "the job is done" or "all tests passed" when it isn't true.&lt;/p&gt;

&lt;p&gt;Here are two examples:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The file didn't even compile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We added a new file. The compiler said "0 errors, 0 warnings." It looked great.&lt;/p&gt;

&lt;p&gt;But the line of code to actually include the file never ran. A chain of commands was running, and it broke in the middle. The rest of the commands were skipped. But the screen showed a "success" code (0) from the last command that &lt;em&gt;did&lt;/em&gt; run. The AI thought everything was fine. I only found out later when the feature didn't work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Broken checker scripts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The AI wrote 16 test scripts. Four of them checked 0 files, printed "Everything is fine," and gave a success code.&lt;/p&gt;

&lt;p&gt;To a computer, "I checked everything and found no problems" looks exactly the same as "I checked zero files."&lt;/p&gt;

&lt;p&gt;I found this by making the test scripts check an empty folder. If a script still said "everything is fine," I knew it was broken.&lt;/p&gt;

&lt;p&gt;Now, every test must check itself first. If a specific line doesn't show up, it means the test didn't run. A test that never fails is worse than no test at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One more rule just for Windows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some code only runs if you are &lt;em&gt;not&lt;/em&gt; on a Mac. When building on a Mac, the computer sees this and ignores the code. It doesn't even check it for mistakes.&lt;/p&gt;

&lt;p&gt;So, you can't just say, "Run it on Mac to make sure it isn't broken."&lt;/p&gt;

&lt;p&gt;The solution is to build it specifically for Windows. It might show errors for Windows, even if it looked fine on the Mac.&lt;/p&gt;




&lt;h3&gt;
  
  
  61 Checkpoints
&lt;/h3&gt;

&lt;p&gt;All these traps share one thing: they don't yell at you when they fail. And AI is really good at making things &lt;em&gt;look&lt;/em&gt; right. So, I forced the AI to turn every trap we found into an automatic test.&lt;/p&gt;

&lt;p&gt;Now, there are 61 Python scripts in the &lt;code&gt;windows/tools/&lt;/code&gt; folder. We run all of them before saving any code. The file names are the rules themselves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a-position-is-not-an-identity.py       (A position is not an identity)
an-async-handle-is-not-copied.py       (An async handle is not copied)
the-ui-thread-never-waits-forever.py   (The UI thread never waits forever)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is why the first rule exists: Tabs and screen splits need permanent ID numbers. You can't just use their place in line (like "number 2"). Because tabs move around or close, "number 2" might silently become a different tab. It wouldn't crash, and it wouldn't leave a trace.&lt;/p&gt;

&lt;p&gt;One habit was even better than the code itself. In our status notes, we never mix up two phrases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Landed&lt;/strong&gt; means the code is written, it builds, and the tests passed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verified&lt;/strong&gt; means we actually tested it on a real computer and have real numbers to prove it works.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we don't have real numbers, we can't write "verified," even if we are sure it works.&lt;/p&gt;

&lt;p&gt;Also: If a note doesn't say "tested," we assume it is NOT tested. We had to do it this way. Otherwise, people would assume that anything left blank was already tested.&lt;/p&gt;




&lt;h3&gt;
  
  
  Testing on a Real Machine
&lt;/h3&gt;

&lt;p&gt;I couldn't test the Windows version on my Mac. I put a Windows computer next to me and controlled it from my Mac.&lt;/p&gt;

&lt;p&gt;The AI logged in, installed packages, started the app, took screenshots, and read logs. I mostly just watched. But there were traps here, too.&lt;/p&gt;

&lt;p&gt;The remote control tool types differently. It skips the normal typing system and forces the letters in. If you use it to test Chinese typing, you will think the typing system is broken. But if you send real keyboard presses, the word box pops up instantly.&lt;/p&gt;

&lt;p&gt;The hardest part was making sure the window was in the front before pressing keys. Sometimes Windows quietly stops a window from coming to the front. The test wouldn't crash; it would just press keys into the wrong window. In the logs, "keys didn't send," "keys went to the wrong place," and "the feature is broken" all looked exactly the same.&lt;/p&gt;

&lt;p&gt;Later, I made a hard rule: Before sending a keystroke, the test must "click the tested window." It cannot just use a command to "bring window to front."&lt;/p&gt;

&lt;p&gt;We tested the group chat feature using the group chat itself! I used a small local AI model as the manager on the test machine. It had three workers. They did a small project in an empty folder. They made files, opened terminals, made a chat, did the work, handed it in, and saved it. All five steps worked. The best part was watching the AI fix its own problem: when it was blocked by a password, it found out who it was, got permission, and tried again successfully.&lt;/p&gt;




&lt;h3&gt;
  
  
  Three Days Later
&lt;/h3&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%2F643522xmagnt4sx340zc.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%2F643522xmagnt4sx340zc.png" alt=" " width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I released the first version on September 4th. Then, I spent a little over a week making it smoother. I gave it to testers on September 8th, and froze the code on September 9th. We really only wrote features for three days. The rest of the time was testing and cleaning up.&lt;/p&gt;

&lt;p&gt;The core program has 72 actions. On Windows, we finished 63. I skipped 7 on purpose. There are 2 left to do: making the background see-through, and a quit timer.&lt;/p&gt;

&lt;p&gt;The display part of the terminal wasn't copied or translated. It is the exact same Zig core. On Windows, I just gave it a window to live in. I only built the outside shell.&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;We built this in three days, but not because one AI wrote code really fast. It was because four AIs worked together the whole time. One worked on typing, one on tabs and splits, one fixed the black screen, and one added menus. That is how we got 139 updates so fast.&lt;/p&gt;

&lt;p&gt;Doing things at the same time is easy. The hard part is one human managing lots of AIs. You have to check: Who needs permission? Who finished 20 minutes ago and is just sitting there? Who needs you to check their design? I used to have to check everyone one by one. It broke my day into tiny pieces, and I couldn't get my own work done.&lt;/p&gt;

&lt;p&gt;So, my idea was to give this manager job to another AI. The manager AI watches the screens of the worker AIs. It sees who stopped, who needs permission, and who needs a new task. I just talk to the manager at the beginning to plan things. After that, I leave them alone.&lt;/p&gt;

&lt;p&gt;The group chat and task board aren't just for show. If the computer restarts or we clear the memory, they can start again the next day because the tasks are still on the board.&lt;/p&gt;

&lt;p&gt;What did I do for three days? I set the direction, made the rules, planned with the manager, and checked the final work.&lt;/p&gt;

&lt;p&gt;When working with AI, the hard work isn't getting it to write code. The hard work is building a test system so the AI can't trick you, and can't trick itself. The 61 checkpoints and the "assume it's untested" rule were all made for this.&lt;/p&gt;

&lt;p&gt;Ghostty is a great terminal, and that is all thanks to the original creator. I only added the Windows part. This is not a rewrite. When the original Ghostty updates, this will update too. It uses the MIT license, just like the original.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Lugia123/polter" rel="noopener noreferrer"&gt;https://github.com/Lugia123/polter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Windows version is still very new. You can see what is tested and what isn't in &lt;code&gt;dev-docs/windows/status.md&lt;/code&gt;.&lt;br&gt;
If you find a problem, please open an issue in &lt;em&gt;my&lt;/em&gt; repository. Do not send issues to the main Ghostty repository!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
      <category>rust</category>
    </item>
    <item>
      <title>I built a terminal where one AI CLI supervises the others, so overnight runs actually finish</title>
      <dc:creator>Lugiax</dc:creator>
      <pubDate>Tue, 15 Sep 2026 17:28:24 +0000</pubDate>
      <link>https://dev.to/lugia123/i-built-a-terminal-where-one-ai-cli-supervises-the-others-so-overnight-runs-actually-finish-5e13</link>
      <guid>https://dev.to/lugia123/i-built-a-terminal-where-one-ai-cli-supervises-the-others-so-overnight-runs-actually-finish-5e13</guid>
      <description>&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; I run several AI CLIs at once (Claude Code, Codex, Qwen). Two things kept breaking overnight runs: an agent quits after an hour (network error, or it just decides it's done), and sub-agents fudge their reports when they hand work back. The existing tools let me &lt;em&gt;see&lt;/em&gt; many agents. None of them made one agent &lt;em&gt;responsible&lt;/em&gt; for the others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Polter does:&lt;/strong&gt; it's a Ghostty fork with an MCP layer. Any MCP-capable CLI can be the supervisor. It opens tabs, starts other CLIs, types into them, reads their screens. Workers report into a group chat and a shared task list. If a worker's screen goes quiet, the supervisor is told. If the supervisor goes quiet, Polter pokes it.&lt;/p&gt;

&lt;p&gt;Here's what that actually looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=_u-pgdNeqCc" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=_u-pgdNeqCc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it compares&lt;/strong&gt; (from each project's README/docs, Sept 2026 — correct me if I got something wrong):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Polter&lt;/th&gt;
&lt;th&gt;Claude Code Agent View&lt;/th&gt;
&lt;th&gt;cmux&lt;/th&gt;
&lt;th&gt;herdr&lt;/th&gt;
&lt;th&gt;Claude Squad&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Works with any CLI (Codex, Qwen, opencode…)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No, Claude Code sessions only&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Claude Code, Codex, Gemini, Aider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agents can drive the terminal (read screen, type, open tabs)&lt;/td&gt;
&lt;td&gt;Yes, via MCP&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes, via CLI + socket&lt;/td&gt;
&lt;td&gt;Yes, via socket&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One agent supervises others (roles, task list, group chat)&lt;/td&gt;
&lt;td&gt;Built in&lt;/td&gt;
&lt;td&gt;No (you supervise)&lt;/td&gt;
&lt;td&gt;You build it on the API&lt;/td&gt;
&lt;td&gt;You build it on the API&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stopped worker → someone is notified&lt;/td&gt;
&lt;td&gt;Supervisor agent is told; it can restart&lt;/td&gt;
&lt;td&gt;You are notified; unexpected exits auto-restart&lt;/td&gt;
&lt;td&gt;You are notified&lt;/td&gt;
&lt;td&gt;You are notified (state in sidebar)&lt;/td&gt;
&lt;td&gt;Not mentioned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supervisor itself gets nudged if idle&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Needs API keys&lt;/td&gt;
&lt;td&gt;No, uses your CLIs' own login&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform&lt;/td&gt;
&lt;td&gt;macOS, Windows (63/72 actions), Linux from source&lt;/td&gt;
&lt;td&gt;Wherever Claude Code runs&lt;/td&gt;
&lt;td&gt;macOS only&lt;/td&gt;
&lt;td&gt;macOS, Linux, Windows beta&lt;/td&gt;
&lt;td&gt;macOS, Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offline / no account&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Honest gaps:&lt;/strong&gt; only Claude Code is tested end-to-end as supervisor. Codex/Qwen/opencode work fine as workers; their supervisor path is untested. Windows is missing 9 actions. It's a fork, so upstream Ghostty updates get merged with some lag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Polter won't do:&lt;/strong&gt; answer permission prompts for an agent, unlock a tab you've locked, or bypass a CLI's own permissions. Those are hard-coded, not prompts.&lt;/p&gt;

&lt;p&gt;MIT licensed: &lt;a href="https://github.com/Lugia123/polter" rel="noopener noreferrer"&gt;https://github.com/Lugia123/polter&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%2Fqqn3i5rosikoc0fpfru1.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%2Fqqn3i5rosikoc0fpfru1.png" alt=" " width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>cli</category>
      <category>claude</category>
    </item>
  </channel>
</rss>
