<?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: İclal Doğan</title>
    <description>The latest articles on DEV Community by İclal Doğan (@iclaldogan).</description>
    <link>https://dev.to/iclaldogan</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%2F3954902%2F2bd39086-cd3f-4b07-9bd7-f830c749f7ea.jpg</url>
      <title>DEV Community: İclal Doğan</title>
      <link>https://dev.to/iclaldogan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iclaldogan"/>
    <language>en</language>
    <item>
      <title>RESIDUES: A Terminal Game Inside the Dying Mind of Alan Turing</title>
      <dc:creator>İclal Doğan</dc:creator>
      <pubDate>Sat, 20 Jun 2026 23:53:24 +0000</pubDate>
      <link>https://dev.to/iclaldogan/residues-a-terminal-game-inside-the-dying-mind-of-alan-turing-2p67</link>
      <guid>https://dev.to/iclaldogan/residues-a-terminal-game-inside-the-dying-mind-of-alan-turing-2p67</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/june-game-jam-2026-06-03"&gt;June Solstice Game Jam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;em&gt;Content note: this game deals with suicide, chemical castration, and the slow breakdown of a mind. It's a story about the death of Alan Turing, told honestly.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;RESIDUES&lt;/strong&gt; is a terminal-native narrative puzzle game, written in Rust, that runs entirely inside your terminal — no graphics window, no mouse, just 24-bit amber phosphor in the dark.&lt;/p&gt;

&lt;p&gt;You are inside the failing mind of Alan Turing on the night of his death — Wilmslow, 8 June 1954. As his cognition collapses, he replays the entire lineage of computing as six interactive puzzles, each one rebuilding the real idea its pioneer gave the world. The principle behind every act is &lt;strong&gt;"Bright Puzzle, Dark Undertow":&lt;/strong&gt; the puzzle in front of you is a clean, genuinely deep technical challenge, while underneath runs the human tragedy of the mind that invented it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Act&lt;/th&gt;
&lt;th&gt;The Mind&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;What you actually do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;I&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Joseph-Marie Jacquard&lt;/td&gt;
&lt;td&gt;1804&lt;/td&gt;
&lt;td&gt;Punch an 8×8 bit matrix into modular cards — a continuous roll tears, a block-chain jams, only a looping deck survives.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;II&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Charles Babbage&lt;/td&gt;
&lt;td&gt;1837&lt;/td&gt;
&lt;td&gt;Derive a baseline by the method of differences, then survive the carry crisis by staggering delay buffers so the carry travels as a wave.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;III&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ada Lovelace&lt;/td&gt;
&lt;td&gt;1843&lt;/td&gt;
&lt;td&gt;Write real assembly on a 3-register machine; overrun the linear cap to unlock loops, then compute a checksum with a loop that devours its own counter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IV&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;George Boole&lt;/td&gt;
&lt;td&gt;1854&lt;/td&gt;
&lt;td&gt;Steer a grid of logic gates to a target checksum while the &lt;em&gt;displayed&lt;/em&gt; output starts lying — but the truth always holds beneath.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;V&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Claude Shannon&lt;/td&gt;
&lt;td&gt;1937&lt;/td&gt;
&lt;td&gt;Assign prefix-free codes within a fixed channel capacity, then add a parity guard against bit-flip noise. Real information theory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Alan Turing&lt;/td&gt;
&lt;td&gt;1936&lt;/td&gt;
&lt;td&gt;Operate a real Turing machine — a head over a tape, a transition table — stabilizing the five prior acts' corrupted residues until the machine reaches HALT.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And the puzzles are &lt;em&gt;real&lt;/em&gt; — not reskinned button-presses. There's a working 7-instruction assembly interpreter, a genuine Turing machine with a complete transition table, real Shannon channel-capacity math, real carry-propagation. &lt;strong&gt;The puzzles ARE the history.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it connects to the jam.&lt;/strong&gt; The June solstice is the year's turning point — the hinge where light begins to lose to darkness. RESIDUES is built entirely on that hinge. Alan Turing was born in June; June is also Pride Month, and the jam itself names him — the father of the Turing Test, persecuted for who he was. Across every act the candle on the desk burns lower, the heartbeat speeds the metronome, and memory corrupts into noise. &lt;em&gt;Light and darkness, the passage of time, a turning point&lt;/em&gt; — those are the jam's own words, and they are the game's three core systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A word before you play.&lt;/strong&gt; Jacquard and Babbage ease you in — the opening acts are gentle, and we're warming you up on purpose. But fair warning: after that, the machine starts asking you to actually &lt;em&gt;think&lt;/em&gt;. If you get stuck somewhere, don't be mad at us — some acts are deliberately demanding with little hand-holding. And if you &lt;em&gt;don't&lt;/em&gt; get stuck? Then you already know this craft, and you have our respect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On Turing's voice.&lt;/strong&gt; Some of you will ask why we gave Turing such a broken, sick, dissolving voice. Here's why: the game dramatizes his final days — the drugs he was forced to take, and the very night he died. There was cyanide in the next room for his experiments and a half-eaten apple by his bed; whether it was an accident, an experiment, or a choice, no one will ever know. We didn't think a man would have a clear, beautiful voice on his last night — so we deliberately didn't give him one. The decay you hear is the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/or6dscTENFs"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;It's a full ~15-minute playthrough, so feel free to skip around — every act is in there. If you're short on time, the chapters in the video description jump straight to the key moments: &lt;strong&gt;Act III (writing real assembly)&lt;/strong&gt;, &lt;strong&gt;Act VI (the Turing machine)&lt;/strong&gt;, and &lt;strong&gt;the ending&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%2F5nspoj4vvki3qxx8w1np.jpeg" 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%2F5nspoj4vvki3qxx8w1np.jpeg" alt=" " width="800" height="419"&gt;&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%2F4twhmhyla1n8x6pdqmn0.jpeg" 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%2F4twhmhyla1n8x6pdqmn0.jpeg" alt=" " width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/miclaldogan" rel="noopener noreferrer"&gt;
        miclaldogan
      &lt;/a&gt; / &lt;a href="https://github.com/miclaldogan/residuesTerminal" rel="noopener noreferrer"&gt;
        residuesTerminal
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Residues: terminal edition — a true-color Rust/Ratatui TUI port (cinematic typewriter prelude, Braille portraits, Jacquard/Babbage acts)
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;RESIDUES — An Engine of Residual Minds&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A terminal-native narrative puzzle game about the birth of computation, written in Rust.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The most terrifying part is learning how to forget."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;RESIDUES runs entirely inside your terminal — no graphics window, no mouse — rendering a truecolor (24-bit) amber-phosphor aesthetic. You are inside the failing mind of Alan Turing on the night of his death (Wilmslow, 8 June 1954). As his cognition collapses, he replays the entire lineage of computing as six interactive puzzles, each one rebuilding the actual idea its pioneer gave the world.&lt;/p&gt;
&lt;p&gt;The design principle is &lt;strong&gt;"Bright Puzzle, Dark Undertow":&lt;/strong&gt; every act is a clean, genuinely deep technical challenge, while underneath runs the human tragedy of the mind that invented it.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The Six Acts&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Each act is a real computational toy — not a reskinned button-press. You don't read &lt;em&gt;about&lt;/em&gt; the machine; you operate one.&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Act&lt;/th&gt;
&lt;th&gt;Mind&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/miclaldogan/residuesTerminal" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;It's genuinely easy to run yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/miclaldogan/residuesTerminal.git
&lt;span class="nb"&gt;cd &lt;/span&gt;residuesTerminal
cargo run &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or zero-install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://raw.githubusercontent.com/miclaldogan/residuesTerminal/main/run.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Play with headphones, in a truecolor terminal.&lt;/strong&gt; The audio is binaural — ghost whispers are hard-panned left and right, and the heartbeat sits under everything — so a lot of the experience is lost on speakers. (The game probes for &lt;code&gt;mpv&lt;/code&gt; / &lt;code&gt;ffplay&lt;/code&gt; / &lt;code&gt;mpg123&lt;/code&gt;; if none is installed it runs completely silent but fully playable — no crash.)&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;RESIDUES is written from scratch in &lt;strong&gt;Rust&lt;/strong&gt; (~10,400 lines, 65 passing tests) on &lt;strong&gt;ratatui + crossterm&lt;/strong&gt;. The challenge wasn't drawing screens — it was making a terminal &lt;em&gt;feel alive&lt;/em&gt;. A few systems do the heavy lifting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A real assembly micro-compiler&lt;/strong&gt; (&lt;code&gt;LOAD/STORE/ADD/SUB/IF_Z/JMP/HALT&lt;/code&gt;) with its own error codes — Lovelace's act is genuinely a register-allocation puzzle, and a &lt;code&gt;[REGISTRY ERROR]&lt;/code&gt; is the &lt;em&gt;narrative&lt;/em&gt; trigger that unlocks loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A crate-free, lock-free audio engine&lt;/strong&gt; that spawns detached OS players, layering an ambient score, rain, hard-panned binaural whispers, and synced voice-overs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A live heartbeat that drives the world&lt;/strong&gt; — the BPM readout isn't decoration; it physically speeds the background metronome, climbing as Turing's interrogation tightens and spiking into arrhythmia on a wrong answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A decay engine&lt;/strong&gt; — as the chemical toxicity rises, the text on screen corrupts into glyphs in real time, so you watch the memory being erased.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A candle that is the only light source&lt;/strong&gt;, with a radial light-degradation engine anchored on the flame, guttering from 100% down to a 5% flicker by the final act.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A PNG → truecolor half-block renderer&lt;/strong&gt; for the cinematic portraits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used Google's &lt;strong&gt;Gemini&lt;/strong&gt; as a brainstorming partner for the historical framing and act structure. The voice and whisper audio was generated with &lt;strong&gt;ElevenLabs&lt;/strong&gt; (paid plan, commercial license).&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Category
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Ode to Alan Turing.&lt;/strong&gt; Turing isn't a tribute bolted on at the end — he's the gravity the whole game falls toward, across all three things the category asks for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mechanics.&lt;/strong&gt; Act VI is a &lt;em&gt;literal&lt;/em&gt; Turing machine: a tape, a moving head, a transition table, and corrupted residues you stabilize until it reaches HALT. You don't read about the Universal Machine — you run one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Narrative.&lt;/strong&gt; His full arc is the climax: breaking Enigma, the silence of the Official Secrets Act, the trial for "gross indecency," the chemical castration, and his last night. The ending — which I'm keeping out of this post on purpose — recontextualizes the entire descent. It's in the video.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design.&lt;/strong&gt; Five centuries of computing — Jacquard's cards, Babbage's gears, Lovelace's loops, Boole's logic, Shannon's entropy — are arranged as a pilgrimage that exists to deliver you to Turing's desk, in his birth month, in a jam built around the very turning point his life embodies.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Solo submission — built and designed by Iclal Doğan.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gamechallenge</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>I Built a 1920s Butler AI That Runs Entirely on My Linux Machine. Then I Abandoned It. Then Copilot Helped Me Fix It.</title>
      <dc:creator>İclal Doğan</dc:creator>
      <pubDate>Sat, 06 Jun 2026 12:22:25 +0000</pubDate>
      <link>https://dev.to/iclaldogan/i-built-a-1920s-butler-ai-that-runs-entirely-on-my-linux-machine-then-i-abandoned-it-then-copilot-5ela</link>
      <guid>https://dev.to/iclaldogan/i-built-a-1920s-butler-ai-that-runs-entirely-on-my-linux-machine-then-i-abandoned-it-then-copilot-5ela</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bantz&lt;/strong&gt; is a local-first, offline-capable AI assistant that runs entirely on your Linux machine. It presents itself as a 1920s English butler — always polite, subtly sarcastic, and absolutely convinced he is a real person standing in the room with you.&lt;/p&gt;

&lt;p&gt;I'm a Turkish speaker on a Linux desktop. Every cloud assistant I tried spoke to me in a foreign language, phoned home to someone else's server, and forgot everything the moment the session ended. I wanted something different: an assistant that speaks Turkish natively, runs on my own hardware, remembers its context, and actually controls my desktop. So I started building Bantz.&lt;/p&gt;

&lt;p&gt;The concept is ambitious. At its core: a Turkish ↔ English translation layer powered by Helsinki-NLP's MarianMT, a multi-step tool planner that can chain web search, Gmail, Calendar, shell commands, filesystem access, and AT-SPI desktop automation — all coordinated by an LLM running locally via Ollama. On top of that: voice I/O via faster-whisper and Piper TTS, persistent memory backed by ChromaDB + a SQLite knowledge graph (MemPalace), a 6-state butler persona that shifts tone based on CPU load and time of day, and a Textual TUI with a live health-status bar.&lt;/p&gt;

&lt;p&gt;The architecture was genuinely interesting. The execution, as of May 2026, was a mess.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub repo:&lt;/strong&gt; &lt;a href="https://github.com/miclaldogan/bantzv2" rel="noopener noreferrer"&gt;github.com/miclaldogan/bantzv2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Broadcast Channel&lt;/strong&gt; — chatting with Bantz, web search + desktop control in action:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2Fseg1.gif" 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%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2Fseg1.gif" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full walkthrough&lt;/strong&gt; — all pages of the Operations Center:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2Fseg5.gif" 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%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2Fseg5.gif" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&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;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2FbantzChat.jpeg" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2FbantzVitals.jpeg" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2FbantzLogs.jpeg" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2FbantzDirectives.jpeg" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2FbantzAnomalyWatch.jpeg" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmiclaldogan%2Fbantzv2%2Fmain%2Fbantz-demo%2FbantzSettings.jpeg" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Before — May 2026
&lt;/h3&gt;

&lt;p&gt;I had a 17-issue backlog and a &lt;code&gt;BROKEN_STATE.md&lt;/code&gt; file I'd written to document the damage. Here's what it said:&lt;/p&gt;

&lt;p&gt;The feature audit was brutal:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Voice input (Whisper)&lt;/td&gt;
&lt;td&gt;🔴 Broken — 3 packages missing, Picovoice key unset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TUI status bar&lt;/td&gt;
&lt;td&gt;❌ Didn't exist&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First-run onboarding&lt;/td&gt;
&lt;td&gt;❌ Blank cursor, zero guidance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-provider LLM support&lt;/td&gt;
&lt;td&gt;🔴 Every finalizer hardcoded &lt;code&gt;ollama&lt;/code&gt; directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Turkish response latency&lt;/td&gt;
&lt;td&gt;🔴 12–18 seconds end-to-end&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;--doctor&lt;/code&gt; diagnostic&lt;/td&gt;
&lt;td&gt;🔴 Actively lying — reported working memory as broken&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TUI rendering&lt;/td&gt;
&lt;td&gt;🔴 Entire layout duplicated on screen after every message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Desktop UI logs&lt;/td&gt;
&lt;td&gt;🔴 WebSocket handler silently crashed on every log event&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The most embarrassing part: I'd built a sophisticated multi-provider LLM router (&lt;code&gt;router.py&lt;/code&gt;) that could dispatch to Claude, OpenAI, Gemini, or Ollama based on config — and then every single callsite in &lt;code&gt;finalizer.py&lt;/code&gt;, &lt;code&gt;summarizer.py&lt;/code&gt;, and the streaming path had just... hardcoded &lt;code&gt;from bantz.llm.ollama import ollama&lt;/code&gt; directly. The router was completely bypassed. Anyone who configured &lt;code&gt;BANTZ_LLM_PROVIDER=claude&lt;/code&gt; would get Ollama responses with no error, no warning, nothing.&lt;/p&gt;

&lt;p&gt;The first-run experience was particularly painful. &lt;code&gt;bantz --once "merhaba"&lt;/code&gt; would hang in complete silence for up to 30 seconds as MarianMT loaded, Ollama inferred, and Piper synthesized — all sequentially, all silently. New users killed the process and never came back.&lt;/p&gt;

&lt;h3&gt;
  
  
  After — June 2026
&lt;/h3&gt;

&lt;p&gt;Seven issues closed in a single focused session, all squash-merged to &lt;code&gt;main&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR #467 — 1-line fix, total silence explained.&lt;/strong&gt; The &lt;code&gt;_WSLogHandler&lt;/code&gt; inside &lt;code&gt;WsBroadcastServer&lt;/code&gt; referenced &lt;code&gt;self._log_q&lt;/code&gt; but the actual queue attribute was &lt;code&gt;self._q&lt;/code&gt;. One character typo. Every log record since the WebSocket server was written had thrown an &lt;code&gt;AttributeError&lt;/code&gt; that got silently swallowed, so the Tauri desktop UI had received zero log output. Fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRs #468 &amp;amp; #469 — The router that wasn't routed to.&lt;/strong&gt; Replaced all three &lt;code&gt;finalizer.py&lt;/code&gt; callsites and the &lt;code&gt;summarizer.py&lt;/code&gt; Gemini/Ollama fallback chain with &lt;code&gt;from bantz.llm.router import get_llm&lt;/code&gt;. Added &lt;code&gt;get_llm = get_provider&lt;/code&gt; as a convenience alias in &lt;code&gt;router.py&lt;/code&gt;. Claude, OpenAI, and Gemini users now actually get their configured provider.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR #470 — Service dots that told the truth.&lt;/strong&gt; The TUI's health-status bar was initialised with the hardcoded key &lt;code&gt;"Ollama"&lt;/code&gt; and &lt;code&gt;_probe_services()&lt;/code&gt; only called &lt;code&gt;check_ollama()&lt;/code&gt;. Added dynamic service key resolution from config, new &lt;code&gt;check_claude()&lt;/code&gt; and &lt;code&gt;check_openai()&lt;/code&gt; coroutines, and a dispatch table to route to the right health check based on the active provider.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR #471 — The TUI duplication bug.&lt;/strong&gt; &lt;code&gt;_erase_prompt_line()&lt;/code&gt; used &lt;code&gt;os.write(1, ...)&lt;/code&gt; to send raw ANSI cursor-movement escapes directly to stdout while Rich Live was simultaneously rendering to the same terminal. This caused a race condition that reproduced the entire TUI block below the real one on every message. The fix: added a &lt;code&gt;Layout(name="prompt", size=1)&lt;/code&gt; panel to the layout tree and replaced the raw write with a state variable (&lt;code&gt;self._prompt_text = ""&lt;/code&gt;). The next Live refresh cycle clears the row cleanly, no escapes needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR #472 — Cutting Turkish response latency from 18s to under 10s.&lt;/strong&gt; Two independent problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;bridge.to_turkish()&lt;/code&gt; ran on the &lt;strong&gt;full accumulated response&lt;/strong&gt; after all LLM inference finished — sequential, never overlapping.&lt;/li&gt;
&lt;li&gt;No caching. Identical butler stock phrases like &lt;code&gt;"Done. ✓"&lt;/code&gt; re-ran the full neural translation model every single time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Added a 256-entry FIFO LRU cache to &lt;code&gt;_Translator&lt;/code&gt; — common phrases now translate in ~0ms after the first call. Then rewrote &lt;code&gt;finalize_stream()._stream()&lt;/code&gt; to buffer LLM tokens until sentence boundaries (&lt;code&gt;(?&amp;lt;=[.!?])\s+&lt;/code&gt;) and call &lt;code&gt;bridge.to_turkish()&lt;/code&gt; per sentence immediately, yielding translated output while the LLM continues generating the next sentence. Translation now overlaps inference instead of running after it. Also removed the redundant &lt;code&gt;await _to_tr("".join(parts))&lt;/code&gt; re-translation in &lt;code&gt;ws_server.py&lt;/code&gt;'s streaming path — &lt;code&gt;finalize_stream&lt;/code&gt; already emits pre-translated tokens when the bridge is enabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issue #463 — Already fixed (no PR needed).&lt;/strong&gt; Copilot confirmed &lt;code&gt;Live(screen=False)&lt;/code&gt; was already set and &lt;code&gt;REFRESH_FPS = 4&lt;/code&gt; was already present. Closed with an explanatory comment. Sometimes the right fix is recognising there's nothing to fix.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I used Copilot in agent mode (Claude Sonnet 4.6) for the entire session. What struck me most was the discipline it brought to a codebase I'd let get messy.&lt;/p&gt;

&lt;p&gt;For every issue, Copilot followed the same workflow without being told to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read the affected file before touching anything.&lt;/strong&gt; Not a summary — the actual file, end-to-end.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search for the exact symbol causing the problem.&lt;/strong&gt; For issue #462, it searched &lt;code&gt;_q|_log_q&lt;/code&gt; in &lt;code&gt;ws_server.py&lt;/code&gt; and immediately surfaced the mismatch. For #465, it searched for every &lt;code&gt;"Ollama"&lt;/code&gt; string literal and found three hardcoded sites at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make the minimal change.&lt;/strong&gt; No unrelated refactors. The &lt;code&gt;_log_q&lt;/code&gt; → &lt;code&gt;_q&lt;/code&gt; fix is literally one word on one line. The router migration replaced 3 identical patterns with identical 2-line substitutions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify syntax before committing.&lt;/strong&gt; &lt;code&gt;python -m py_compile &amp;lt;file&amp;gt;&lt;/code&gt; on every changed file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the commit message and PR body, then create and merge the PR via &lt;code&gt;gh&lt;/code&gt;.&lt;/strong&gt; Including verifying the issue closed with &lt;code&gt;gh issue view NNN --json state&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most valuable moment was on issue #422 (translation latency). I knew the translation was slow but I'd assumed it was just a hardware limitation — MarianMT on CPU takes what it takes. Copilot traced the full data flow from &lt;code&gt;finalize_stream()&lt;/code&gt; through &lt;code&gt;ws_server.py&lt;/code&gt; and identified that the bottleneck wasn't just the model — it was the architecture: sequential execution after completion, plus identical inputs being re-translated on every call. The sentence-boundary streaming approach it introduced had never occurred to me, and it worked on the first try.&lt;/p&gt;

&lt;p&gt;The other moment I appreciated: issue #463. Rather than making a change to justify its existence, Copilot searched for &lt;code&gt;screen=&lt;/code&gt; in &lt;code&gt;live_ui.py&lt;/code&gt;, confirmed the value was already &lt;code&gt;False&lt;/code&gt;, checked &lt;code&gt;REFRESH_FPS&lt;/code&gt;, and told me the issue was already resolved. Closing a bug report with "this is already fixed" is the correct outcome. That kind of restraint is hard to get from a tool optimised to produce output.&lt;/p&gt;

&lt;p&gt;Bantz isn't finished, voice input still needs its three packages, the &lt;code&gt;--doctor&lt;/code&gt; output still needs polish, and I want to add a proper onboarding flow. But the core pipeline now works correctly for all supported LLM providers, the TUI renders cleanly, Turkish responses arrive in under 10 seconds, and the butler's logs finally reach the desktop UI. That's a project that went from "broken in embarrassing ways" to "actually ships" — and Copilot was the pairing partner that made it happen in a single afternoon.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
