<?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: Kame｜local-first tools</title>
    <description>The latest articles on DEV Community by Kame｜local-first tools (@dkamehat).</description>
    <link>https://dev.to/dkamehat</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%2F3960034%2F681073b2-0bde-4091-86fb-23e3e4682d66.png</url>
      <title>DEV Community: Kame｜local-first tools</title>
      <link>https://dev.to/dkamehat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dkamehat"/>
    <language>en</language>
    <item>
      <title>"Before you let an AI say \"I found a vulnerability\" — on changing my aim, and throwing away my own finding"</title>
      <dc:creator>Kame｜local-first tools</dc:creator>
      <pubDate>Sun, 05 Jul 2026 16:26:30 +0000</pubDate>
      <link>https://dev.to/dkamehat/before-you-let-an-ai-say-i-found-a-vulnerability-on-changing-my-aim-and-throwing-away-my-2m3b</link>
      <guid>https://dev.to/dkamehat/before-you-let-an-ai-say-i-found-a-vulnerability-on-changing-my-aim-and-throwing-away-my-2m3b</guid>
      <description>&lt;p&gt;AI-assisted vulnerability research has a quiet but decisive step before the flashy "I found a 0-day": confirming that the thing is actually novel, and actually a defect. This is the record of aiming an authorization-scoped testing harness at three mature open-source projects, black-box-rediscovering a real CVE-class bug on a non-obvious surface — and then declining to report it, because it turned out to be an already-fixed public CVE. No exploit here. Only the method, and public CVE numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What I built — an authorization-scoped harness
&lt;/h2&gt;

&lt;p&gt;Three parts: (a) a deny-by-default egress scope-lock that mechanically refuses traffic to anything not explicitly allowed; (b) an append-only ledger that enforces the human sign-off at the data layer (a vulnerability is "confirmed" by a human gate, never by the LLM); (c) a coordinated-vulnerability-disclosure (CVD) pipeline that separates the steps you may automate from the steps that stay human. On top of that, I black-box test self-hosted OSS using two of my own accounts (self-A / self-B) and compare. No offensive reconnaissance (no unauthorized scanning, no hunting for victims). Only a self-hosted lab I solely occupy, with synthetic data.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. First, an honest non-finding
&lt;/h2&gt;

&lt;p&gt;I began by systematically attacking the "horizontal IDOR on primary CRUD" surface of three mature targets (two task managers and a no-code DB): "can B read A's object by id?" The result was 403 across the board, zero findings. This is not failure — it is the correct result, because the front door is exactly what popular OSS hardens most. What matters is being able to record "there was nothing here" honestly. Green does not mean working; I front-loaded an A-control (legitimate access returning 200 + a known marker) every time, so the "non-finding" is one where false positives were already eliminated — which is what makes the later claim trustworthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Changing the aim — judgment over target selection
&lt;/h2&gt;

&lt;p&gt;The hypothesis: real authorization bugs live in code paths that don't pass the per-object permission check — aggregation (group by), relation expansion (linked records / lookups), derived reads (export, notifications, feeds), and the leaks in "intended" sharing (shared views). If the front door is hard, don't switch targets; switch the surface you aim at.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The re-aimed run hit on the first try
&lt;/h2&gt;

&lt;p&gt;Aimed at a no-code DB's public shared-view, one cycle of black-box differential testing reproduced two over-exposures. First, a column hidden in the view returned its raw values through the aggregation endpoint. Second, records from an unshared related table returned through the relation-expansion endpoint. The decisive clue was an inconsistency: the main row-fetch API strictly enforced the column-hiding, while the auxiliary endpoints did not. "The main path enforces it but the auxiliary path doesn't" is not decoration — it is the signature of an ACL bypass.&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%2Fr2w85neiuqfdxpgzd1k9.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%2Fr2w85neiuqfdxpgzd1k9.png" alt=" " width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. And then I threw away my finding
&lt;/h2&gt;

&lt;p&gt;This is the point. Before shouting "0-day," I checked public advisories (touching nothing on the target, reading only public information). The two reproductions were already published and fixed as CVE-2026-47378 (hidden-column leak via aggregation, cross-table related-data) and CVE-2026-47279 (the public shared-view relation endpoint not checking column visibility). I further confirmed, deterministically from a version/build diff, that the instance I tested was running pre-fix code due to a distribution-channel lag. Therefore this is not a novel 0-day — it is a reproduction of known CVEs on an out-of-date build. So I do not report it: sending an already-public, already-fixed CVE as a "new discovery" is duplicate noise and a breach of discipline. I recorded it as dismissed, honestly.&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%2F0up2g0ydrh6u0eksklw3.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%2F0up2g0ydrh6u0eksklw3.png" alt=" " width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. The lesson — judgment beats bug count
&lt;/h2&gt;

&lt;p&gt;Two things are true at once. First, the method rediscovered real CVE-class authorization bugs, black-box, on exactly the non-obvious surfaces theory predicted (three "front-door" cycles found nothing; one "re-aimed" cycle found two CVE-class issues). Aim mattered. Second — and just as important — the discipline to recognize "reproduced != novel" and stop myself from over-claiming. AI-assisted research earns trust not through flash, but by verifying before it shouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. What I do NOT include (explicit)
&lt;/h2&gt;

&lt;p&gt;No exploit, no PoC. I never touched the target's production (a self-hosted synthetic lab only). What I publish is the method and public CVE numbers. No unfixed or undisclosed vulnerability appears in this article.&lt;/p&gt;




&lt;p&gt;Stories about flashy discoveries are everywhere. What's rare is the story of "I thought I found something, verified it, and threw it away." The more powerful automation gets, the more this discipline is worth.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>bugbounty</category>
      <category>devsecops</category>
    </item>
    <item>
      <title>Your fixtures rot because they encode yesterday's schema. So I regenerate mine — deterministically.</title>
      <dc:creator>Kame｜local-first tools</dc:creator>
      <pubDate>Thu, 02 Jul 2026 12:12:05 +0000</pubDate>
      <link>https://dev.to/dkamehat/your-fixtures-rot-because-they-encode-yesterdays-schema-so-i-regenerate-mine-deterministically-gi0</link>
      <guid>https://dev.to/dkamehat/your-fixtures-rot-because-they-encode-yesterdays-schema-so-i-regenerate-mine-deterministically-gi0</guid>
      <description>&lt;p&gt;Two moments broke me on hand-written seed data.&lt;/p&gt;

&lt;p&gt;The first: fresh clone, migrations pass, app boots — and every screen is blank, because a database with perfect structure and zero rows can't show you anything. So you hand-write INSERTs in dependency order, or a Faker script, and the script promptly references a user that doesn't exist.&lt;/p&gt;

&lt;p&gt;The second, worse one: CI. Integration tests need a seeded DB, and they need the &lt;strong&gt;same&lt;/strong&gt; DB every run or the suite goes flaky. Hand-written fixtures deliver the opposite — they're frozen at whatever the schema looked like the day you wrote them, and every migration after that is a fixture-maintenance tax.&lt;/p&gt;

&lt;p&gt;Both problems have the same root cause: &lt;strong&gt;the data is hand-maintained while the schema keeps moving.&lt;/strong&gt; So I built a CLI that regenerates the data from the schema, deterministically. It's called &lt;strong&gt;Veriseed&lt;/strong&gt;, and I want to be precise about what's shipped versus what's a bet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually live today (free, open source)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One command:&lt;/strong&gt; &lt;code&gt;npx veriseed seed --schema ./prisma/schema.prisma&lt;/code&gt; → a single transactional SQL file (&lt;code&gt;BEGIN; … COMMIT;&lt;/code&gt;) for Postgres&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FK-correct by construction:&lt;/strong&gt; tables are topologically ordered (parents before children) and every child FK is picked from parent keys that were &lt;em&gt;actually generated&lt;/em&gt; — no orphans&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic:&lt;/strong&gt; &lt;code&gt;--seed 42&lt;/code&gt; (the default) → &lt;strong&gt;byte-identical SQL on every run&lt;/strong&gt;, regenerated from your &lt;em&gt;current&lt;/em&gt; schema. Commit the command, not the fixtures — they can't rot, and CI stops flaking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volume:&lt;/strong&gt; &lt;code&gt;--rows 50000&lt;/code&gt; if you want to see your pagination and N+1s at something like real scale — I've verified 200k INSERTs across a 4-table schema in ~2.6s, locally&lt;/li&gt;
&lt;li&gt;Parses Prisma (&lt;code&gt;@id&lt;/code&gt;, &lt;code&gt;@relation&lt;/code&gt;, &lt;code&gt;@map&lt;/code&gt;/&lt;code&gt;@@map&lt;/code&gt;, enums, optionals, &lt;code&gt;@default&lt;/code&gt;), light lookup-based locale coherence (name, city, country agree within a row)&lt;/li&gt;
&lt;li&gt;Zero dependencies, no account, no API key; once installed it runs offline
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx veriseed demo
npx veriseed seed &lt;span class="nt"&gt;--schema&lt;/span&gt; ./prisma/schema.prisma &lt;span class="nt"&gt;--rows&lt;/span&gt; 500 &lt;span class="nt"&gt;--seed&lt;/span&gt; 42 &lt;span class="nt"&gt;--out&lt;/span&gt; seed.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To be equally clear about what Core is &lt;strong&gt;not&lt;/strong&gt;: the values aren't AI-realistic. The coherence is lookup-based, not generative. What you get is &lt;em&gt;structurally correct, reproducible&lt;/em&gt; data — which turned out to be what my actual problems needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Can't I just ask an AI chat for this?"
&lt;/h2&gt;

&lt;p&gt;For a one-off sample to eyeball — yes, honestly, and you don't need my tool for that. A chat LLM will even produce more lifelike values than my Core does. Where chat falls over is exactly where this tool starts: it truncates past a few dozen rows, it invents parent IDs that don't exist, it gives you &lt;em&gt;different&lt;/em&gt; data every ask (hello flaky CI), and it can't run unattended in a pipeline. If your seeding is one-off and small, use chat. If it's &lt;strong&gt;repeated, structural, or at scale&lt;/strong&gt;, that's what Veriseed is for.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Isn't this just Faker plus a toposort?"
&lt;/h2&gt;

&lt;p&gt;Mostly, yes — and that glue is exactly what you keep rewriting. Faker has no schema awareness: &lt;em&gt;you&lt;/em&gt; write the toposort, the FK-value-picking from generated parent PKs, the per-row coherence, and a fresh script per schema — then patch it all after every migration. Veriseed does that from the schema, deterministically, as one transactional file. The value is the glue, not AI magic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bet I'm validating: Pro
&lt;/h2&gt;

&lt;p&gt;Core doesn't mask PII, doesn't subset a big graph into a referentially-intact slice, and doesn't do deep realism. That's the &lt;strong&gt;Pro&lt;/strong&gt; layer — designed to run on a &lt;strong&gt;local model&lt;/strong&gt;, keeping everything on your machine. Can a local model clear a usable realism bar? &lt;strong&gt;Unproven&lt;/strong&gt; — that's literally what the &lt;strong&gt;$19 founding pre-order&lt;/strong&gt; funds me to find out. It locks the founding price (planned $38 at launch) and is &lt;strong&gt;fully refundable if it doesn't ship&lt;/strong&gt;. I'd rather tell you that than fake a demo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it / follow the build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Free core (OSS, MIT): &lt;strong&gt;&lt;a href="https://github.com/dkamehat/veriseed" rel="noopener noreferrer"&gt;https://github.com/dkamehat/veriseed&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Landing + founding pre-order: &lt;strong&gt;&lt;a href="https://veriseed.netlify.app" rel="noopener noreferrer"&gt;https://veriseed.netlify.app&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your seed script broke on the last migration — or your E2E suite is flaky because the fixtures drifted — tell me where. That's the roadmap.&lt;/p&gt;

</description>
      <category>postgressql</category>
      <category>prisma</category>
      <category>cli</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I built Koe: fully-local, offline voice dictation for Windows (faster-whisper + Ollama)</title>
      <dc:creator>Kame｜local-first tools</dc:creator>
      <pubDate>Sun, 28 Jun 2026 02:17:18 +0000</pubDate>
      <link>https://dev.to/dkamehat/i-built-koe-fully-local-offline-voice-dictation-for-windows-faster-whisper-ollama-jal</link>
      <guid>https://dev.to/dkamehat/i-built-koe-fully-local-offline-voice-dictation-for-windows-faster-whisper-ollama-jal</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Koe&lt;/strong&gt; is a voice dictation tool for Windows: you tap a key, speak, and clean text is typed into whatever app has focus. The whole pipeline — transcription &lt;em&gt;and&lt;/em&gt; cleanup — runs on your own machine. Nothing is ever sent to the cloud.&lt;/p&gt;

&lt;p&gt;It's open-source (MIT): &lt;a href="https://github.com/dkamehat/Koe" rel="noopener noreferrer"&gt;https://github.com/dkamehat/Koe&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%2F19g7213n1plzeu4bfpt8.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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F19g7213n1plzeu4bfpt8.gif" alt=" " width="760" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;The inspiration is &lt;a href="https://withaqua.com/" rel="noopener noreferrer"&gt;Aqua Voice&lt;/a&gt;. The "press a key, talk, get clean text in any app" experience is genuinely great — but I had two constraints:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No subscription&lt;/strong&gt; — I wanted it to be free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing leaves the machine&lt;/strong&gt; — for some of my work, my voice and on-screen content simply can't go to a third party.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The only way to satisfy both is to run everything locally. So I set the thesis up front: &lt;strong&gt;it must run locally, and it should be something anyone can use safely.&lt;/strong&gt; Every decision flows from that.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; mic ─► record ─► faster-whisper ─► dictionary ─► refiner ─► clipboard paste ─► app
          ①          ②(CUDA)        proper nouns   local LLM    Unicode-safe       ④
                                                 (context-grounded, streamed)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STT&lt;/strong&gt;: &lt;a href="https://github.com/SYSTRAN/faster-whisper" rel="noopener noreferrer"&gt;faster-whisper&lt;/a&gt; (CTranslate2) on CUDA / float16, &lt;code&gt;large-v3-turbo&lt;/code&gt; by default. Handles English and Japanese.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleanup ("refiner")&lt;/strong&gt;: an optional &lt;strong&gt;local LLM via Ollama&lt;/strong&gt; (&lt;code&gt;qwen2.5&lt;/code&gt;) removes fillers, adds punctuation, and fixes proper-noun spelling — while &lt;strong&gt;preserving your exact wording and never translating&lt;/strong&gt;. Cloud backends (Claude/OpenAI) exist but are opt-in, bring-your-own-key, and selecting one automatically disables the screen-context grounding so nothing leaves the box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context grounding&lt;/strong&gt;: it reads the focused window/field locally so it spells code identifiers right (say "get user by id" → types &lt;code&gt;get_user_by_id&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-healing dictionary&lt;/strong&gt;: correct a term once and it sticks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Things I learned the hard way
&lt;/h2&gt;

&lt;p&gt;Getting something that &lt;em&gt;works&lt;/em&gt; was the easy part. Making it &lt;em&gt;fast and pleasant&lt;/em&gt; is where the real lessons were.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;localhost&lt;/code&gt; cost me ~2.2 seconds per request on Windows
&lt;/h3&gt;

&lt;p&gt;It felt like 3–5 seconds from "stop talking" to "text appears," and I assumed the model was slow. But when I actually measured, inference was fine. The culprit: &lt;strong&gt;Python's &lt;code&gt;requests&lt;/code&gt; resolving &lt;code&gt;http://localhost:11434&lt;/code&gt; on Windows hits an IPv6→IPv4 fallback that cost ~2.2s per request.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Switching to &lt;code&gt;http://127.0.0.1:11434&lt;/code&gt; (plus reusing a &lt;code&gt;requests.Session&lt;/code&gt; with &lt;code&gt;trust_env=False&lt;/code&gt;) dropped the cleanup step from ~2.6s to ~0.3–0.5s. That was ~90% of my "latency problem." Lesson: on Windows, don't use &lt;code&gt;localhost&lt;/code&gt; for a local HTTP service from Python — measure before you optimize.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Whisper still hallucinates repetition loops
&lt;/h3&gt;

&lt;p&gt;On silence or noise, Whisper can fall into a loop, emitting the same token over and over (&lt;code&gt;シャッシャッシャッ…&lt;/code&gt; × 100). Even with the usual guards (&lt;code&gt;compression_ratio_threshold&lt;/code&gt;, temperature fallback, VAD) it occasionally slips through — and then the LLM cleanup step dutifully chews on a thousand repeated tokens, wasting ~10 seconds.&lt;/p&gt;

&lt;p&gt;The fix that actually held: a &lt;strong&gt;deterministic post-processing guard&lt;/strong&gt; that collapses any short unit repeated 6+ times in a row down to a single occurrence. Normal speech never does that, so it's safe — and it stops the garbage from ever reaching the user or the LLM.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Fixing the clipped first word with "preroll"
&lt;/h3&gt;

&lt;p&gt;The instant you press the key, mic driver start-up latency eats the first syllable ("…ello" instead of "Hello"). The fix: keep an &lt;strong&gt;always-on ring buffer&lt;/strong&gt; running, and when you start a take, prepend the ~0.3s &lt;em&gt;before&lt;/em&gt; the keypress. First word intact.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Keeping the local LLM from "improving" too much
&lt;/h3&gt;

&lt;p&gt;Left alone, a local LLM loves to paraphrase — and sometimes to &lt;em&gt;translate&lt;/em&gt;. The first time my Japanese came back as English, I was surprised. Beyond a hardened "preserve wording, never translate, minimal edits" prompt, I added a &lt;strong&gt;deterministic language guard&lt;/strong&gt;: if the input contains CJK but the output dropped all of it (or vice-versa), the LLM result is discarded and rule-based formatting is used instead. For dictation, predictable beats clever.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Packaging CUDA into a standalone .exe
&lt;/h3&gt;

&lt;p&gt;"Anyone can use it" means a build that runs without Python or git. PyInstaller handles the app, but the CUDA DLLs (cuBLAS/cuDNN) are the tricky part. CTranslate2's loader only searches &lt;strong&gt;its own package directory and the bundle root&lt;/strong&gt; — not arbitrary subfolders — so the DLLs have to sit at the root. On top of that, PyInstaller's nvidia hooks were collecting the same DLLs into a second location; dropping those duplicates saved ~650 MB. Final result: a ~1.2 GB zip you can download, unzip, and run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# A) Download (no Python needed)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;#    Grab Koe-win64-cuda.zip from the Releases page, unzip, run Koe.exe&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# B) From source&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://github.com/dkamehat/Koe.git&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Koe&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;\setup.ps1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;\run-admin.bat&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tap Right Ctrl once to start, speak (pause and think freely), tap again to stop → cleaned text lands in the focused app.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;With the foundation in place, I'm prototyping a &lt;strong&gt;live meeting interpreter&lt;/strong&gt; on the same local stack — local English subtitles + Japanese translation for the other side of a Zoom/Meet call. The hard part is WASAPI loopback capture and streaming endpointing. More on that later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;You can build genuinely useful voice input without giving up "local-only and safe for anyone." A surprising amount of the work was chasing unglamorous culprits — the biggest "slowness" was DNS resolution, not the model. Measure first, then fix.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/dkamehat/Koe" rel="noopener noreferrer"&gt;https://github.com/dkamehat/Koe&lt;/a&gt; — feedback very welcome.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
