<?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: Syed Masood Shah</title>
    <description>The latest articles on DEV Community by Syed Masood Shah (@syed_masoodshah_1984).</description>
    <link>https://dev.to/syed_masoodshah_1984</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%2F4063074%2F001d22d5-adcd-4649-b439-879cb18c9f81.png</url>
      <title>DEV Community: Syed Masood Shah</title>
      <link>https://dev.to/syed_masoodshah_1984</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/syed_masoodshah_1984"/>
    <language>en</language>
    <item>
      <title>The model didn't mistranslate the film. It rewrote it.</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Wed, 26 Aug 2026 13:38:25 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/the-model-didnt-mistranslate-the-film-it-rewrote-it-dnn</link>
      <guid>https://dev.to/syed_masoodshah_1984/the-model-didnt-mistranslate-the-film-it-rewrote-it-dnn</guid>
      <description>&lt;p&gt;The moment things got weird was around the third scene. A character said one short line, and my dub played a long, wordy stretch that I didn't recognize. I rewound, read it, and it clicked: nothing was mistranslated. The model had &lt;em&gt;rewritten&lt;/em&gt; the line. Tidy, polished, and somehow longer than anything that was actually spoken.&lt;/p&gt;

&lt;p&gt;I'd built LiveDub, a little tool where a browser extension grabs a tab's audio, Whisper turns it into text, a local LLM translates it, and Kokoro speaks the result out loud over the original. All of it runs on my PC, so I had trace logs over everything. The culprit was never the speech-to-text part.&lt;/p&gt;

&lt;p&gt;It was the translation step.&lt;/p&gt;

&lt;p&gt;Here's what I hit: local LLMs today are damn eager to help. Hand one a sentence in one language and ask for it in another, and a lot of them won't do the single, literal thing you asked. They guess your job is film adaptation. They fill in the actor's mood. They compress three lines into something sharper. Professional translators are trained to do the opposite, but we don't hand them a fresh prompt every line.&lt;/p&gt;

&lt;p&gt;On paper the output looked good. Better, some sessions, than the subtitles in the actual movie, which is the trap. I was re-captioning a film scene by scene, so every reinterpretation pushed the audio a beat off the actors' mouths, and the extra words dragged the synthesized voice so long that whole exchanges drifted.&lt;/p&gt;

&lt;p&gt;The fix was the system prompt, and it took me three attempts to get the tone right. The version that won looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a faithful interpreter. Translate the exact meaning and tone, nothing more.
Do not expand, condense, or paraphrase for drama, and do not add your own reaction.
If the line is short and flat, return short and flat. Output only the translated line.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last line - "output only the translated line" - is the one that carried the most weight. LLMs respond to instructions about the shape of the reply almost as much as to what's in it. Give them nothing to perform into.&lt;/p&gt;

&lt;p&gt;It took a couple of hours of back-and-forth to land on that balance. The day it clicked was unglamorous: a flat, slightly rude, two-word line came back as a flat, slightly rude, two-word line. Almost dull to watch, and that was the win. With real-time dubbing tooling, success isn't a better rendering. It's a faithful one, and no more.&lt;/p&gt;

&lt;p&gt;If you're pointing a local LLM at translation, don't work around it line by line. Bake the constraint into the prompt first, guard the shape, and test against lines you already know. And if you're curious how the whole thing hangs together - browser tab audio capture for any video, streaming Whisper, voice switching by pitch - I packaged the complete offline Windows-only tool at &lt;a href="https://symshah.gumroad.com/l/livedub" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/livedub&lt;/a&gt; for a one-time $19. No cloud, no monthly bill, no the model quietly "improving" your script.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A year of meetings, and my minutes are plain text files on my own disk</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Wed, 26 Aug 2026 13:32:19 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/a-year-of-meetings-and-my-minutes-are-plain-text-files-on-my-own-disk-175n</link>
      <guid>https://dev.to/syed_masoodshah_1984/a-year-of-meetings-and-my-minutes-are-plain-text-files-on-my-own-disk-175n</guid>
      <description>&lt;p&gt;I've sat through a lot of meetings. The kind where you walk out, someone emails "what did we decide?" and nobody can agree. That's the reason I started dumping every meeting into a tool called Local Meeting Notes instead of trusting the built-in recorder. But what sold me in the long run wasn't the summaries. It was that the output is just text I actually own.&lt;/p&gt;

&lt;p&gt;The app records the mic plus system audio. Teams, Zoom, Meet, or a room. Whisper does the transcription on my CPU, and LM Studio (free, any small model loaded) turns that raw transcript into structured minutes: a summary, the key decisions, action items with owners and dates where people said them, and open questions. Then it exports to Markdown, text, or PDF.&lt;/p&gt;

&lt;p&gt;The Markdown part is the sleeper feature. Every meeting becomes a plain file. I keep them in one folder, one per meeting, and grep across all of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-ri&lt;/span&gt; &lt;span class="s2"&gt;"deadline"&lt;/span&gt; notes/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one line has settled more arguments than any meeting tool I've used. Someone claims we never agreed to ship by Friday? Past week's minutes, in the terminal, on the spot. No logging into a portal, no "trial expired," no export that turns into a tidy PDF I can't search later.&lt;/p&gt;

&lt;p&gt;That's what keeps annoying me about meeting-notes SaaS. Your minutes live in their database, formatted their way, and the day you stop paying, the search goes with them. Local files with dates in the filename don't vanish. They don't get upgraded into a format half my terminal tools choke on. They sit there as long as the disk does.&lt;/p&gt;

&lt;p&gt;PDF export exists for the people who need something to attach to an email or file away. But honestly, if a meeting matters, I want it as text where regex works.&lt;/p&gt;

&lt;p&gt;The practical bits, since that's the part people actually ask about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Needs Windows 10/11 and Python 3.10+. LM Studio is free and you don't need a big model; a small one writes perfectly fine minutes.&lt;/li&gt;
&lt;li&gt;Runs on CPU. Transcription gets chatty on an older laptop but it works; a GPU just makes the Whisper step faster.&lt;/li&gt;
&lt;li&gt;Before you record anyone, check whether recording is regulated where you work and get consent. That's on you whether it's a client call or a one-on-one. This is a tool for your own minutes, not a way to dodge the question.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole thing is $9 one-time at symshah.gumroad.com/l/xgoypx. No account, no subscription, nothing uploaded.&lt;/p&gt;

&lt;p&gt;What I actually got out of this wasn't shinier meeting notes. It's that I stopped re-litigating what was decided, because the answer lives in a folder on my machine I can actually search.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>ai</category>
      <category>localllm</category>
      <category>windows</category>
    </item>
    <item>
      <title>The server got hit and I only knew because a file quietly changed itself</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Wed, 26 Aug 2026 13:27:55 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/the-server-got-hit-and-i-only-knew-because-a-file-quietly-changed-itself-4b50</link>
      <guid>https://dev.to/syed_masoodshah_1984/the-server-got-hit-and-i-only-knew-because-a-file-quietly-changed-itself-4b50</guid>
      <description>&lt;p&gt;Nobody ever gets excited about file integrity monitoring. It's the security control you configure once, forget about, and only remember exists when the auditor asks for a change log. I get it. It's not shiny. But last month it's the only thing that told me something was wrong.&lt;/p&gt;

&lt;p&gt;I run a small business infrastructure stack — a few self-hosted services, a couple of public-facing containers, the usual. One morning I got an alert that a binary inside a running container had been modified. Not by a deploy. Not by me. A base image hash had changed when nothing in the pipeline had pushed.&lt;/p&gt;

&lt;p&gt;That single alert started it. I dug in, found the container needed patching, and it turned out to be a legit supply-chain issue on the image. Harmless in the end. But the point stuck with me: the whole time, not one log line screamed. The firewall didn't care. The IDS didn't flinch. The only evidence was a file that changed when it shouldn't have.&lt;/p&gt;

&lt;p&gt;That's what file integrity monitoring actually buys you. It's not watching logs. It's watching the filesystem and saying "this hash is not what it was, and nothing authorized changed it."&lt;/p&gt;

&lt;p&gt;I use Wazuh for this. It runs as a Docker stack, which is the only way I'd get a small business to adopt it at all. Wazuh does the agent-side monitoring, so each host reports what files changed, when, and against what baseline. It keeps a running collection of known-good hashes and flags anything that drifts.&lt;/p&gt;

&lt;p&gt;The part I care about as an admin is that I can tune it. Left alone, FIM alerts on everything and you get a wall of noise that teaches you to ignore it. So I lay out the known-good paths first, then scope the monitoring to the things that actually matter: binaries, config files, web root. Cron thinks it owns /tmp? I don't want ten thousand alerts a day about it.&lt;/p&gt;

&lt;p&gt;For a small shop the realistic pattern is: install the agent on the hosts you care about, let it build a baseline for a few days, then set alerts on checksum changes and new files appearing in sensitive directories. Keep the frequency sane. Every second is overkill; once a minute is plenty to catch a compromise without melting the disk.&lt;/p&gt;

&lt;p&gt;The other thing FIM doubles as is an audit trail that most small businesses don't have. When the auditor asks what changed on your server in the last 30 days, a Wazuh dashboard beats a shrug and a hope. You can pull up exactly the file, the timestamp, and who was on the box.&lt;/p&gt;

&lt;p&gt;This is one of the three stacks in the SMB Security Pack I sell — SIEM, an IPS with a Grafana dashboard, and encrypted restic backups. All Docker, all self-hosted, one-time $15. The FIM piece is buried in the SIEM stack and it's the quietest part of the setup, but it's the one that earns its keep when something sneaks through everything else.&lt;/p&gt;

&lt;p&gt;If you run servers for a business and your only alarm is reading logs after the fact, that's a gap. FIM is cheap to set up and it covers a blind spot nobody else does.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>infrastructure</category>
      <category>monitoring</category>
      <category>security</category>
    </item>
    <item>
      <title>I stopped pasting my company's code into free chatbots. A local model is where it lives now.</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Wed, 26 Aug 2026 13:26:37 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/i-stopped-pasting-my-companys-code-into-free-chatbots-a-local-model-is-where-it-lives-now-1p30</link>
      <guid>https://dev.to/syed_masoodshah_1984/i-stopped-pasting-my-companys-code-into-free-chatbots-a-local-model-is-where-it-lives-now-1p30</guid>
      <description>&lt;p&gt;I watched an engineer paste a chunk of our internal codebase into a free chatbot the other day. He didn't think twice. And honestly, I don't blame him, because for a long time there was no good alternative. It was either the free cloud thing or nothing.&lt;/p&gt;

&lt;p&gt;Here's the thing nobody says out loud: every prompt you type into those services is training data or a support ticket or both. And when the prompt is a function from your company's proprietary system, that's not a harmless question. That's a leak you didn't even notice.&lt;/p&gt;

&lt;p&gt;I'm the IT and network admin here. Part of my job is being the guy who says the uncomfortable thing about data. So a while back I set myself a rule: anything that touches company IP does not leave this building. And if I wanted the convenience of an AI assistant, that meant I needed one that runs inside my four walls.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that changed my mind
&lt;/h2&gt;

&lt;p&gt;The shift wasn't about benchmark scores. It was about the phrase "what goes in stays in." I can look at the machine that's running my LLM and know exactly what it does with my text. No ambiguous privacy policy, no third party in the chain, no terms of service that changed overnight. That peace of mind is the whole point.&lt;/p&gt;

&lt;p&gt;And for my day-to-day work, the local model is genuinely good enough. I use it to explain odd log lines, to draft awkward IT emails, to sanity-check a firewall rule before I click apply. Nothing in that list needs a frontier model. It needs something that understands the question and won't rat me out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The practical bit
&lt;/h2&gt;

&lt;p&gt;Getting it up and running isn't a weekend project. It's more like an afternoon. You need three pieces working together: a model runner, a friendly web interface, and Docker to glue it together. The setup that finally stuck for me looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# three pieces, one docker compose file&lt;/span&gt;
lmstudio        &lt;span class="c"&gt;# runs the quantized model locally&lt;/span&gt;
open-webui      &lt;span class="c"&gt;# the chat frontend everyone on the team can use&lt;/span&gt;
watchtower      &lt;span class="c"&gt;# keeps the images from going stale&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quantized models are the secret that makes this feasible on hardware you already own. A 4-bit quantized model runs fine on a machine that would choke on the full version. You trade a little fluency for a lot of privacy, and for internal use it's a trade I make every time.&lt;/p&gt;

&lt;p&gt;The engineers can still get their answers. The difference is those answers now cost nothing, leak nothing, and nobody has to explain to a data-protection officer why our source code is sitting in someone else's logs.&lt;/p&gt;

&lt;p&gt;That's the pitch, really. Not a faster AI. A safer one. If you've ever winced watching someone hand your company's internals to a stranger, I put together a bundle that walks you through the whole local setup, start to finish, at &lt;a href="https://symshah.gumroad.com/l/selfhosted-ai-homelab" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/selfhosted-ai-homelab&lt;/a&gt;. It's pay-what-you-want, and it's built for people who'd rather host their own brain than rent one.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>localai</category>
      <category>selfhosted</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Windows won't record its own calls. I fixed it with a loopback instead</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Mon, 24 Aug 2026 13:30:13 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/windows-wont-record-its-own-calls-i-fixed-it-with-a-loopback-instead-llk</link>
      <guid>https://dev.to/syed_masoodshah_1984/windows-wont-record-its-own-calls-i-fixed-it-with-a-loopback-instead-llk</guid>
      <description>&lt;p&gt;The part nobody warns you about when you decide to keep meeting recordings on your own machine is that Windows won't just let you record what you're hearing. Out of the box, it doesn't.&lt;/p&gt;

&lt;p&gt;The mic is easy. Windows grabs that fine. But the far end of a Teams or Zoom or Meet call, the voices of everyone on the other side, those arrive through your speakers or headset. And there is no stock setting that says "also record that." Go look. I'll wait.&lt;/p&gt;

&lt;p&gt;The standard answer is WASAPI loopback. It lets one program tap into your output device and pull the samples before they become sound, the same trick screen recorders lean on when they promise to also capture system audio. It's not exotic, but it's fiddly, and it's the part nobody writes about — because transcription and the LLM writing the summaries are the fun half. The capture is the boring half. It's also the part that decides whether your minutes actually cover both sides of the conversation.&lt;/p&gt;

&lt;p&gt;Getting it right means handling a few things not in the blog posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loop back clean, not the audio that's already been through your chosen volume or any of the meeting flavor sounds.&lt;/li&gt;
&lt;li&gt;The feed comes straight off the device, so your job is matching it against what's coming out and what's coming in, without letting either get stomped.&lt;/li&gt;
&lt;li&gt;If the timing between system audio and your mic drifts, the transcript goes incoherent and the minutes are worthless. A conversation where people cut each other off needs both streams landing in the right order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a real engineering problem, the kind you don't notice until it's wrong.&lt;/p&gt;

&lt;p&gt;What I actually built is a small Windows app that records the mic and the system audio at the same time via that loopback, transcribes it locally with Whisper through faster-whisper, then passes the transcript to a small local model in LM Studio to write actual minutes — Summary, Key Decisions, Action Items with owners and dates when people said them, Open Questions. Export to Markdown, plain text, or PDF.&lt;/p&gt;

&lt;p&gt;The reason that matters is the whole thing runs on my PC. No account, no subscription, nothing uploaded. The audio never leaves my machine. It genuinely doesn't. A GPU makes Whisper faster, but it all runs on CPU if that's all you've got.&lt;/p&gt;

&lt;p&gt;One honest note, because it's true and it fits: recording meetings may be regulated where you work. Check your org's policy and get consent before you record people. The point isn't to record people in secret — it's to not have your meeting audio leave your machine at all.&lt;/p&gt;

&lt;p&gt;Plenty of tools will transcribe your meetings for free, because you're the product and the audio is theirs to keep. I didn't want that. The ride where you're wondering which vendor's model is digesting your weekly staff all-hands is worse than just fixing the loopback once.&lt;/p&gt;

&lt;p&gt;If the whole problem sounds like one you'd rather just have solved, I made it a small Windows app. $9 one time, no subscription, real code finally writing the minutes the meetings never did. &lt;a href="https://symshah.gumroad.com/l/xgoypx" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/xgoypx&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>windows</category>
      <category>localllm</category>
      <category>ai</category>
    </item>
    <item>
      <title>Cloud translation costs me a rent and a delay. My local dubber does neither.</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Mon, 24 Aug 2026 01:35:26 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/cloud-translation-costs-me-a-rent-and-a-delay-my-local-dubber-does-neither-3kkf</link>
      <guid>https://dev.to/syed_masoodshah_1984/cloud-translation-costs-me-a-rent-and-a-delay-my-local-dubber-does-neither-3kkf</guid>
      <description>&lt;h1&gt;
  
  
  Cloud translation costs me a rent and a delay. My local dubber skipped both.
&lt;/h1&gt;

&lt;p&gt;I watch a fair amount of Korean and Japanese stuff, and for a while I did the obvious thing: rented a cloud service to translate it as it played. It worked, sort of. But it also cost me a monthly bill, made me keep an eye on network latency, and quietly shipped every scrap of dialogue audio up to someone else's server.&lt;/p&gt;

&lt;p&gt;So I rebuilt the same pipeline to run entirely on the machine in front of me. That gap became the whole point of the tool.&lt;/p&gt;

&lt;p&gt;The setup is simpler than I'd have guessed. A browser extension pulls the tab audio. Whisper transcribes it in pieces, a small model inside LM Studio translates the text, and a neural TTS (Kokoro) speaks it while the original audio ducks underneath so you still hear the scene. Nothing has to leave your PC. No GPU required (it helps). Python 3.10+, LM Studio, and a translation model around 2GB.&lt;/p&gt;

&lt;p&gt;People always ask about the delay, so I'll be straight about it. There's a natural lag of a sentence or two. That's not me being lazy. No dubbing tool on the planet can start translating a line until the speaker finishes it, because the translation depends on what the whole sentence means. The cloud has that same delay, plus a round trip on top of it. The local version waits the same sentence boundary, then starts speaking almost immediately. It ends up closer to real-time, and it doesn't cost a thing per minute.&lt;/p&gt;

&lt;p&gt;The part that surprised me was voices. Whisper gives me the spoken text, and if I measure the pitch of the source speaker, the TTS can pick a lower register for a male voice and a higher one for a female, automatically. It's one small threshold in code, and it drags the whole thing out of robotic territory. A cloud service would've billed me per line for that.&lt;/p&gt;

&lt;p&gt;The economics are what really pushed me local. Cloud translation isn't something you buy once; it's a rent you keep paying, and it only ever gets faster when you pay a pricier tier. A local translator is a one-time purchase that runs on hardware I already own, works offline after setup, and never counts characters. For someone who watches foreign films a few times a week, the math stopped being close.&lt;/p&gt;

&lt;p&gt;If you watch a lot of subtitled cinema and you're tired of sending every second of audio to a server, I built a small Windows app plus a browser extension that does the whole chain locally, tab audio to Whisper to a local LLM to a natural voice. It's nineteen dollars. &lt;a href="https://symshah.gumroad.com/l/livedub" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/livedub&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>When the auditor asked if my backups actually worked, I had a screenshot instead of a shrug</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Mon, 24 Aug 2026 01:26:33 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/when-the-auditor-asked-if-my-backups-actually-worked-i-had-a-screenshot-instead-of-a-shrug-1ane</link>
      <guid>https://dev.to/syed_masoodshah_1984/when-the-auditor-asked-if-my-backups-actually-worked-i-had-a-screenshot-instead-of-a-shrug-1ane</guid>
      <description>&lt;p&gt;The auditor asked me a question I couldn't answer, and the room got quiet.&lt;/p&gt;

&lt;p&gt;"Show me a successful restore."&lt;/p&gt;

&lt;p&gt;I had the backup tool configured. I had the jobs running every night. I had the little green checkmark in some admin panel saying everything was fine. What I did not have was any actual proof I'd ever restored anything. I handed them a shrug when I should have been pulling up a screen.&lt;/p&gt;

&lt;p&gt;That's the thing nobody tells you about backups. Backing up is the easy ten percent. The other ninety is knowing the thing restores, knowing it restores recently, and being able to say so out loud without crossing your fingers. Plenty of small businesses treat the backup button like a retirement plan, and it goes expensive the exact week they need it.&lt;/p&gt;

&lt;p&gt;So I stopped treating restores like an emergency procedure and started treating them like a chore that lands on a schedule, same as rotating logs or patching a server. Every couple of weeks I pick a snapshot, drop it into a scratch folder, and confirm the files that matter actually survived the trip through the archive. Then I write the result down.&lt;/p&gt;

&lt;p&gt;Here's the part that sounds small and isn't. I keep that result visible on a small audit dashboard, so "did I actually verify anything this month" isn't a memory game. It's a line that says last verified restore, how big it was, how many files, zero errors. When someone asks if the backups are good, I don't produce a story. I turn the screen around and let the numbers talk.&lt;/p&gt;

&lt;p&gt;The command that makes this possible in a way you can point at is boring in the best way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;restic restore 42a1b82c &lt;span class="nt"&gt;--target&lt;/span&gt; /tmp/restest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you look in that folder, see your files, log one line saying it worked. That's it. There's no ceremony in a good restore test. There's just a habit you keep and a record to show.&lt;/p&gt;

&lt;p&gt;If you want that workflow automated, the stack I've been building does exactly this: an encrypted backup layer that snapshots and audits itself, plus a small dashboard that tells the truth about the last time something came back out of the archive. No SaaS billing, no vendor deciding what "backed up" means, and it runs on a spare laptop. One-time buy over at symshah.gumroad.com/l/smb-security-pack.&lt;/p&gt;

&lt;p&gt;The auditor never asked me twice. That's the whole point. People only ask once when your answer is verifiable instead of a vibe.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I stopped chasing the one perfect model. Now I run three small ones.</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Mon, 24 Aug 2026 01:25:22 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/i-stopped-chasing-the-one-perfect-model-now-i-run-three-small-ones-4h1b</link>
      <guid>https://dev.to/syed_masoodshah_1984/i-stopped-chasing-the-one-perfect-model-now-i-run-three-small-ones-4h1b</guid>
      <description>&lt;p&gt;For months I was the guy chasing a single model to rule them all. Every weekend I'd pull down the newest quantized weights, run a few test prompts, mutter, and load the old one back. Meanwhile the thing I do for a living kept smacking me in the face: nobody in IT runs one tool for everything. You keep the right wrench for the right bolt. Cloud models trained that reflex out of me, at first.&lt;/p&gt;

&lt;p&gt;You sign into the cloud one, you get the frontier model, and you never ask yourself again. Then I went fully self-hosted at home, and I realized I didn't have to pick one at all. Owning a model means you get to split what it does.&lt;/p&gt;

&lt;p&gt;So I run three. Not more. Each is quantized small enough to sit on hardware I already own, and each one is bad at the thing the other two are good at. That's the job.&lt;/p&gt;

&lt;p&gt;The chat one is the workhorse. It stays warm in Open WebUI all day and takes the boring questions — "write this email," "make this doc shorter," "what's wrong with this YAML." It doesn't need to be 70 billion to do that. My family uses the same one and doesn't know it's running in the living room; it's just fast and it doesn't ask about their stuff.&lt;/p&gt;

&lt;p&gt;The coding one is picky. It gets the jobs that are half-written already and just need to be careful — keep the imports right, don't refactor the whole file while you're in there. Slower, but it argues less.&lt;/p&gt;

&lt;p&gt;And the math one is the one I almost never admit to keeping. It's stubborn and wrong a surprising amount. But when it's right, it's right, and I got tired of a generalist confidently mangling my numbers. A specialist is wrong in a predictable lane; a generalist is wrong everywhere.&lt;/p&gt;

&lt;p&gt;This reads like overkill, I know. But the whole point of self-hosting is that a second small model costs almost nothing. Some disk, a rounding error of power. What I got back was my attention. No more model-hop weekends, no more second-guessing whether the tool is the thing that's wrong. Small model, small job, move on.&lt;/p&gt;

&lt;p&gt;What shifts when you stop renting the biggest brain is the question you're even asking. It stops being "is this as smart as the cloud's best?" and becomes "is this better than what I was doing last week?" And that one you can answer on a Tuesday with normal hardware in the corner of your desk, without sending a single token anywhere.&lt;/p&gt;

&lt;p&gt;If you want that exact setup without wiring it from twenty GitHub tabs, I packaged what I settled on — LM Studio, Open WebUI, Docker, the quantized models, plus the monitoring and backups so you aren't running this in a vacuum. Pay what you want, $9.99 suggested, nothing leaves the building. &lt;a href="https://symshah.gumroad.com/l/selfhosted-ai-homelab" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/selfhosted-ai-homelab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sit with the smaller models. You'll find the fast one does, honestly, most of it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>selfhosted</category>
      <category>privacy</category>
      <category>openwebui</category>
    </item>
    <item>
      <title>I stopped using my meeting app's built-in recorder (compliance nightmare, and it gives you a transcript, not minutes)</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Sat, 22 Aug 2026 13:27:25 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/i-stopped-using-my-meeting-apps-built-in-recorder-compliance-nightmare-and-it-gives-you-a-kbn</link>
      <guid>https://dev.to/syed_masoodshah_1984/i-stopped-using-my-meeting-apps-built-in-recorder-compliance-nightmare-and-it-gives-you-a-kbn</guid>
      <description>&lt;p&gt;My meeting app has a built-in recorder. Click the button, it records, it transcribes. Sounds great until you actually need the output.&lt;/p&gt;

&lt;p&gt;For a start, half the time it's the wrong side of the call. Screen-share captures the presenter's voice in one channel and leaves everyone else muddy, or it only records what one person said, or it quietly depends on the host being on the right plan to even give you the file. And every one of those recordings is sitting in someone's cloud before you've ended the call.&lt;/p&gt;

&lt;p&gt;Then there's the output. You get a transcript. A wall of text. Sixty people saying a lot of words, none of them agreed to anything, and you're the one who's supposed to turn it into minutes at 9pm.&lt;/p&gt;

&lt;p&gt;I built something instead. It records the mic and system audio on my own PC - which means it catches a Teams call, a Zoom, or a person sitting across a table, all the same way. Uses WASAPI loopback so it grabs what the app is playing, not a screen recording with a voice on top. Then Whisper transcribes it locally, and a small LLM in LM Studio reads the transcript and writes the minutes the way I would if I'd paid attention all meeting: a Summary, the Key Decisions, the Action Items with owners and dates where anyone actually said one, and the Open Questions nobody answered.&lt;/p&gt;

&lt;p&gt;Export to Markdown, text, or PDF. Done. No account, no subscription, no upload.&lt;/p&gt;

&lt;p&gt;That last part isn't a slogan, it's the whole design. The audio never leaves the machine. Whisper runs here. The model that writes the minutes runs here. There's no pipeline that even could send it anywhere, which is kind of the point when your employer's setup treats every recording as a thing to be governed.&lt;/p&gt;

&lt;p&gt;One honest note: recording meetings may be regulated where you work, and whether your colleagues know they're being recorded is a genuine question, not a checkbox. Get consent, read your policy, then use a tool that doesn't make the situation worse by also spraying the audio to a third party.&lt;/p&gt;

&lt;p&gt;You don't need a monster machine. Windows 10 or 11, Python 3.10+, and LM Studio running any small model - it chews through a 45-minute meeting on CPU fine; a GPU just makes the transcription snappier.&lt;/p&gt;

&lt;p&gt;I put it up as a one-time thing for $9: &lt;a href="https://symshah.gumroad.com/l/xgoypx" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/xgoypx&lt;/a&gt;. No surprise monthly charge like the apps it replaced. Install it, point it at a meeting, and see if you actually stop dreading the minutes.&lt;/p&gt;

&lt;p&gt;People who attend meetings get to doze off. One of you still has to write it down. Might as well be a local model instead of you.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>ai</category>
      <category>windows</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Getting Tab Audio Out of a Browser Was the Hardest Part of My Dubbing Tool</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Fri, 21 Aug 2026 13:32:18 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/getting-tab-audio-out-of-a-browser-was-the-hardest-part-of-my-dubbing-tool-7da</link>
      <guid>https://dev.to/syed_masoodshah_1984/getting-tab-audio-out-of-a-browser-was-the-hardest-part-of-my-dubbing-tool-7da</guid>
      <description>&lt;p&gt;I keep getting asked what the hardest part of building a real-time dubbing tool was. Most people assume it's the model. It wasn't. The week that made me question my life choices was spent on something far dumber: capturing just one tab's audio and handing it to a process on my own machine, without recording my whole desktop or a mic track of me muttering at the screen.&lt;/p&gt;

&lt;p&gt;A browser tab isn't a file on disk. You can't point at it like a URL and slurp it. The audio is being rendered live inside an open page, surrounded by however many other tabs and whatever else the OS happens to be playing. Record the desktop and you get everything, half of it other people's notifications. Grab the mic and you get your own voice layered over the track, which is worse. The honest answer is to live inside the page itself, as the thing that taps the stream before it ever reaches the system mixer. An extension running in the tab is the only thing that gets you exactly the one piece of audio you're trying to read, and none of the noise.&lt;/p&gt;

&lt;p&gt;Once that's working, the rest is a pipeline I've written about in pieces before, so here's the wide view: the extension shuttles audio frames to a local Whisper that transcribes in slices rather than waiting for the whole film, each slice goes to a local model in LM Studio for translation, and a neural TTS called Kokoro speaks the result with one of two voices picked by the pitch of the original speaker. All of it happens on a Windows box with Python 3.10+ and a small model around 2GB. Nothing leaves the machine, and once the initial setup is done the whole thing runs with the network cable unplugged.&lt;/p&gt;

&lt;p&gt;The streaming part is where the plumbing actually earns its keep. You can't translate a movie as one giant block, you'd be wrapping up sometime after the post-credits scene. So Whisper gets fed in short windows, each window comes back as a sentence, and each sentence only gets translated once the speaker has finished it. That's the couple-of-words delay every tool like this has. It's not a flaw, it's a rule of the game: you cannot speak a line you haven't heard yet. A real-time studio sitting on a ten-thousand-dollar GPU box lives under the same constraint.&lt;/p&gt;

&lt;p&gt;Loosely, the loop looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;video&lt;/span&gt; &lt;span class="n"&gt;plays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait_for_next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="c1"&gt;# audio grabbed by the extension
&lt;/span&gt;    &lt;span class="n"&gt;line&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;whisper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transcribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# local transcription
&lt;/span&gt;    &lt;span class="n"&gt;out&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;local_llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# LM Studio, not the cloud
&lt;/span&gt;    &lt;span class="n"&gt;voice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pick_for_pitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kokoro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;voice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;duck_and_play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;# original audio dips underneath
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When that finally clicked, the payoff felt borderline unfair. I put a French crime film on with a Spanish dub track and it kept pace in something close to real time while the original volume ducked underneath. No GPU required, though a decent one tightens the gap between a sentence ending and the next one landing.&lt;/p&gt;

&lt;p&gt;If you'd rather watch a whole working pipeline than solder these pieces together yourself, I packaged it as a single Windows download, browser extension, local transcription, translation, and voice choosing, one up-front price and no subscription: &lt;a href="https://symshah.gumroad.com/l/livedub" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/livedub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>localllm</category>
      <category>whisper</category>
      <category>python</category>
    </item>
    <item>
      <title>My firewall logs were a scrollable list of bots. I let a shared blocklist do the reading.</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Fri, 21 Aug 2026 13:24:01 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/my-firewall-logs-were-a-scrollable-list-of-bots-i-let-a-shared-blocklist-do-the-reading-1f4</link>
      <guid>https://dev.to/syed_masoodshah_1984/my-firewall-logs-were-a-scrollable-list-of-bots-i-let-a-shared-blocklist-do-the-reading-1f4</guid>
      <description>&lt;p&gt;The internet has been knocking on my firewall all day, and I'd stopped reading the logs long ago.&lt;/p&gt;

&lt;p&gt;Not much to see, honestly. Same parade of bots every time — someone spraying the default admin password, a scanner probing for a debug endpoint I don't actually run, a botnet family I've seen so many times I could name them on sight. None of them ever got in. So I ignored the flood. That's allowed, right? Until one of them stops being noisy and finds a way in. That's the part we all tend to skip.&lt;/p&gt;

&lt;p&gt;What finally changed my habits was giving the boring logs a job to do instead of a human to scroll past. I stood up a layer of my security stack that does not just watch traffic — it acts on it, fast, and it turns tired log rows into a blocklist that gets smarter the longer it runs.&lt;/p&gt;

&lt;p&gt;Here's how it works in plain terms. CrowdSec watches live traffic, and the moment something behaves like an attacker — a run of failed logins, a sweep across ports, one bot telegraphing exactly what it's after — that IP gets flagged and turned away. But the bit that sold me is that the intel is shared. CrowdSec publishes what it sees to a community signal. What some other admin's server caught today ends up on mine by tonight, and the things my box catches get pushed out to everyone else running the same setup too. Security is usually a lonely business of staring at your own logs. This one has a crowd behind it.&lt;/p&gt;

&lt;p&gt;Don't take my word for it being worth it, though. If I can't see a thing working, I'll start to doubt it inside a week. So the same pack gives me a Grafana board that turns all of it into a glance while the coffee brews:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# what did my network block while I was asleep?&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:8080/api/v1/decisions"&lt;/span&gt; | python &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-40&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I get blocks by source, top offenders, and which attacks got flung at me that day. Quietly satisfying, watching a daily batch of scanners get turned away by a list other people's servers helped build.&lt;/p&gt;

&lt;p&gt;One honest gotcha: the first week I ran it at the strictest setting, and a client's visit caught a ban. If you have real users, expect to loosen the thresholds and actually read the dashboard when someone reports the site went down. False positives measure themselves fast — and at least they're showing up somewhere you're looking.&lt;/p&gt;

&lt;p&gt;That layer is one of the three tools in the security pack I run, and it's the piece I'd genuinely miss first. It's $15 one-time, updates included: &lt;a href="https://symshah.gumroad.com/l/smb-security-pack" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/smb-security-pack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyway. The raw logs finally talk to me somewhere I'll actually listen now.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>security</category>
      <category>selfhosted</category>
      <category>sysadmin</category>
    </item>
    <item>
      <title>Why I stopped renting a chatbot and run Open WebUI at home instead</title>
      <dc:creator>Syed Masood Shah</dc:creator>
      <pubDate>Fri, 21 Aug 2026 13:22:56 +0000</pubDate>
      <link>https://dev.to/syed_masoodshah_1984/why-i-stopped-renting-a-chatbot-and-run-open-webui-at-home-instead-1nod</link>
      <guid>https://dev.to/syed_masoodshah_1984/why-i-stopped-renting-a-chatbot-and-run-open-webui-at-home-instead-1nod</guid>
      <description>&lt;p&gt;I got tired of the ChatGPT export. You know the one, the "download your history" button that exists so you can technically leave if you want to. I used it four times in a year, and every time it just confirmed that my prompts, my threads, my half-finished code sat on someone else's servers with my name on them.&lt;/p&gt;

&lt;p&gt;So when I started messing with local models, the first thing I actually wanted wasn't raw inference. Raw inference is fun for an afternoon, then you realize you miss the chat UI. The history. The threads. The context.&lt;/p&gt;

&lt;p&gt;That's where Open WebUI came in. It's a self-hosted web interface that looks and feels like the chatbot you're used to. It runs in Docker, connects to whatever model backend you've got running, and keeps all your chats in a local database. Not a vendor's cloud. A database on your machine.&lt;/p&gt;

&lt;p&gt;Honestly, setup is a single container. The bare version of it is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -p 3000:8080 --name open-webui ghcr.io/openwebui/open-webui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Point it at your model backend, sign in once, and suddenly you've got a chatbot that doesn't phone home. My prompts stay in my house. My threads stay in my house. If my internet blips at 9pm, mine still answers, because nothing needs to leave the machine. That's the whole pitch in one sentence.&lt;/p&gt;

&lt;p&gt;What actually sold me is the flow of it. I do a fair bit of support work and admin, so I ask a lot of small questions. Sending each of those to a hosted chat means every one flows through a third party and lands in someone's logs. With my own web UI pointed at a local quantized model, the cost of a trivial question is basically zero, so I ask more of them. That's the part nobody tells you about self-hosting: you use the AI more, not less, because asking never feels like a leak.&lt;/p&gt;

&lt;p&gt;Now the honest part. Local models have limits, and I won't pretend otherwise. A machine you own runs smaller models than the frontier ones do. But a well-quantized 7-9B model handles my typical jobs fine, drafting and summarizing and gluing things together. It's only when I need deep reasoning that I feel the gap. The trick is treating it like any other tool and matching the size to the job.&lt;/p&gt;

&lt;p&gt;If you want a home lab without assembling the pieces yourself, I put together the Self-Hosted AI Home Lab as a bundle, pay what you want from nine dollars. That's LM Studio, Open WebUI, Docker, and a set of quantized models, all self-hosted, no cloud, ready to tinker with. &lt;a href="https://symshah.gumroad.com/l/selfhosted-ai-homelab" rel="noopener noreferrer"&gt;https://symshah.gumroad.com/l/selfhosted-ai-homelab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll take a chat that never leaves my house over renting one that does. The history button can wait forever.&lt;/p&gt;

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