<?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: Akhouri Anmol Kumar</title>
    <description>The latest articles on DEV Community by Akhouri Anmol Kumar (@akhourianmolkumar).</description>
    <link>https://dev.to/akhourianmolkumar</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%2F3977056%2F5246045a-21af-48c6-a210-77be340f73e4.jpeg</url>
      <title>DEV Community: Akhouri Anmol Kumar</title>
      <link>https://dev.to/akhourianmolkumar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akhourianmolkumar"/>
    <language>en</language>
    <item>
      <title>What's Your Favorite Car, and Why? (Mine Is the Lamborghini Urus, and Yes, I'll Defend It)</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Tue, 13 Oct 2026 12:58:23 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/whats-your-favorite-car-and-why-mine-is-the-lamborghini-urus-and-yes-ill-defend-it-2c5f</link>
      <guid>https://dev.to/akhourianmolkumar/whats-your-favorite-car-and-why-mine-is-the-lamborghini-urus-and-yes-ill-defend-it-2c5f</guid>
      <description>&lt;p&gt;Description: "A car-lover's discussion thread for developers: pick one car, defend it, and tell us the story behind it. Plus a tangent about keys, locks, and the things we protect."&lt;br&gt;
tags: discuss, watercooler, security, python&lt;/p&gt;

&lt;p&gt;Let's get one thing out of the way: this is &lt;strong&gt;not&lt;/strong&gt; a "which car has the best 0-100" thread.&lt;/p&gt;

&lt;p&gt;Spec sheets are boring. Anyone can paste a Wikipedia table.&lt;/p&gt;

&lt;p&gt;What I want is the &lt;em&gt;real&lt;/em&gt; answer. The car that makes your chest do something stupid when you hear it start. The one you'd pick if someone handed you exactly one key and said, &lt;em&gt;"This is the only car you'll ever drive again."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So here's the deal. I'll go first, then it's your turn. 🏁&lt;/p&gt;




&lt;h2&gt;
  
  
  🐂 My pick: the Lamborghini Urus
&lt;/h2&gt;

&lt;p&gt;Yes, the SUV. Yes, &lt;em&gt;that&lt;/em&gt; one.&lt;/p&gt;

&lt;p&gt;I can already hear the purists typing. "A Lamborghini is supposed to be low, loud, and impractical!" Fair. For decades, that was the whole identity.&lt;/p&gt;

&lt;p&gt;But here's why the Urus is my favorite, and it's not the badge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's the audacity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Someone at Lamborghini looked at the brand's entire reputation and said: &lt;em&gt;"What if we built a twin-turbo V8 monster that also fits your family, your luggage, and your groceries, and it still feels like a bull that escaped its pen?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's an insane brief. It's like being told:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Build a tool that's incredibly powerful, but also usable by normal humans, and don't you dare make it feel watered down."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every developer knows how hard that is. Power and usability usually fight each other. Most products pick a side. The Urus refused to.&lt;/p&gt;

&lt;p&gt;And look at what it does with that refusal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strada, Sport, Corsa:&lt;/strong&gt; one car, multiple personalities, switched with a dial.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terra, Sabbia, Neve:&lt;/strong&gt; it has modes for &lt;em&gt;dirt, sand, and snow&lt;/em&gt;. A Lamborghini. For &lt;em&gt;sand&lt;/em&gt;. 😂&lt;/li&gt;
&lt;li&gt;Air suspension, torque vectoring, rear-wheel steering. A 2+ ton machine that rotates like something half its size.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It doesn't show off its cleverness. It just quietly rearranges itself so that you feel like a better driver than you are.&lt;/p&gt;

&lt;p&gt;That's the exact feeling I chase when I write software. The best systems protect you from yourself while still feeling &lt;em&gt;wild&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The Urus is basically a monolith that somehow scales. 🔥&lt;/p&gt;




&lt;h2&gt;
  
  
  🔑 The part nobody talks about: the &lt;em&gt;key&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Here's a tangent that turned into an obsession.&lt;/p&gt;

&lt;p&gt;Think about how a modern car protects itself. It's honestly beautiful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;key fob&lt;/strong&gt; isn't just a button. It's a tiny cryptographic handshake.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;immobilizer&lt;/strong&gt; refuses to let the engine fire unless the right "answer" comes back.&lt;/li&gt;
&lt;li&gt;Rolling codes mean that even if someone records your signal, replaying it is useless.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yet, thieves still beat it. Relay attacks. Signal amplification. Cheap gadgets that cost less than your last tire.&lt;/p&gt;

&lt;p&gt;Why? Because &lt;strong&gt;the lock was strong, but the assumptions around it were weak.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That sentence has haunted me ever since, because it's &lt;em&gt;exactly&lt;/em&gt; the problem with how most of us protect our digital lives. We buy a fantastic lock and then leave the spare key under the doormat: a password reused in five places, a "private" folder named &lt;code&gt;private&lt;/code&gt;, a text file called &lt;code&gt;passwords_final_v2.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You know the one. Don't pretend you don't. 😅&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ So I built myself a garage (for files, not cars)
&lt;/h2&gt;

&lt;p&gt;This is where the car obsession and the coding obsession collided.&lt;/p&gt;

&lt;p&gt;I got tired of "security" tools that were either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a shiny UI wrapped around nothing, or&lt;/li&gt;
&lt;li&gt;so complicated you needed a degree to lock one PDF.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I built &lt;strong&gt;ATLOCK&lt;/strong&gt;, a single-(.exe), Windows-first security suite written in pure Python. The newest version, &lt;strong&gt;ATLOCK v5&lt;/strong&gt;, is the one I'm proudest of. And the Urus is honestly the best way I can describe the philosophy: &lt;strong&gt;one machine that does everything, without feeling like a compromise.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of it like a proper garage:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;In the car world&lt;/th&gt;
&lt;th&gt;In ATLOCK v5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The ignition key + immobilizer&lt;/td&gt;
&lt;td&gt;Your master password, hardened with &lt;strong&gt;Argon2id&lt;/strong&gt; (it makes brute-forcing painfully expensive)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The reinforced steel door&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;AES-256-GCM&lt;/strong&gt; chunked encryption, so every chunk of your file is independently authenticated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A second key fob&lt;/td&gt;
&lt;td&gt;Optional &lt;strong&gt;Keyfile&lt;/strong&gt; or &lt;strong&gt;hardware key (FIDO2 / YubiKey)&lt;/strong&gt;: the file needs your password &lt;em&gt;and&lt;/em&gt; the physical thing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The glovebox for sensitive stuff&lt;/td&gt;
&lt;td&gt;A built-in &lt;strong&gt;password vault&lt;/strong&gt;, with import from Bitwarden / Chrome / Firefox / KeePass / 1Password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spare key in a safe place&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Shamir secret sharing&lt;/strong&gt;: split a recovery key into shares so no single person holds the whole thing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The tamper alarm&lt;/td&gt;
&lt;td&gt;Self-integrity checks, anti-debug checks, and a &lt;strong&gt;canary&lt;/strong&gt; system that notices when something is poking around&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Just like the Urus has its Strada/Sport/Corsa dial, ATLOCK has plain-language helpers like &lt;code&gt;--getting-started&lt;/code&gt; and &lt;code&gt;--device-health&lt;/code&gt; (it checks things like BitLocker and hibernation settings), so beginners and power users both feel at home. A lock nobody understands is a lock nobody uses.&lt;/p&gt;

&lt;p&gt;If you want to poke at it yourself, v5 is here, and you just extract the zip and run the &lt;code&gt;.exe&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK/releases/download/v5.0.0/ATLOCK_v5.zip" rel="noopener noreferrer"&gt;Download ATLOCK v5&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The most "car guy" thing I did: I wrote down what it &lt;em&gt;can't&lt;/em&gt; do
&lt;/h2&gt;

&lt;p&gt;Every good manufacturer prints the real limits in the manual. (Looking at you, "do not exceed X rpm.")&lt;/p&gt;

&lt;p&gt;So at the very top of the ATLOCK source, I wrote an &lt;strong&gt;honest security notes&lt;/strong&gt; section. A few of my favorites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A same-user attacker who can run code as you can modify a Python script and read its memory. Integrity checks &lt;em&gt;raise the cost&lt;/em&gt;; they don't make you invincible.&lt;/li&gt;
&lt;li&gt;Python strings are immutable, so wiping a password from RAM is &lt;strong&gt;best-effort&lt;/strong&gt;, not a guarantee.&lt;/li&gt;
&lt;li&gt;"Secure shredding" on SSDs can't be promised, because wear-levelling keeps old blocks around. &lt;strong&gt;BitLocker is the real fix.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It isn't code-signed and uses no kernel driver. It's an &lt;em&gt;application-layer&lt;/em&gt; product, and I say so out loud.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think that's the most important lesson I took from loving cars: &lt;strong&gt;trust comes from honesty about limits&lt;/strong&gt;, not from a marketing slogan that says "unhackable."&lt;/p&gt;

&lt;p&gt;Nothing is unhackable. Anyone who tells you otherwise is selling something.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Okay, your turn. Seriously.
&lt;/h2&gt;

&lt;p&gt;I told you mine. Now the floor is yours. Drop a comment with:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Your favorite car&lt;/strong&gt; (any era, any country, any budget, even if it's a rusty hatchback)&lt;br&gt;
&lt;strong&gt;2. The &lt;em&gt;reason&lt;/em&gt; behind it&lt;/strong&gt;, with the story, not the spec sheet&lt;br&gt;
&lt;strong&gt;3. Bonus round:&lt;/strong&gt; the car you'd &lt;em&gt;never&lt;/em&gt; trust with your keys, and why 😄&lt;/p&gt;

&lt;p&gt;To get the ball rolling, here are some questions to chew on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is your favorite car the one you &lt;em&gt;own&lt;/em&gt;, the one you &lt;em&gt;drove once&lt;/em&gt;, or the one on your bedroom wall as a kid?&lt;/li&gt;
&lt;li&gt;Do you love &lt;strong&gt;raw and analog&lt;/strong&gt; (manual gearbox, no assists), or &lt;strong&gt;smart and surgical&lt;/strong&gt; (the car does half the thinking)?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hot take:&lt;/strong&gt; can an SUV &lt;em&gt;ever&lt;/em&gt; be a "real" supercar-brand car? Or is the Urus a betrayal? Fight me in the comments. 🥊&lt;/li&gt;
&lt;li&gt;Would you trade a faster car for one that's more &lt;em&gt;reliable&lt;/em&gt;? Be honest.&lt;/li&gt;
&lt;li&gt;Is there a car tied to a person: a dad's old sedan, a friend's first ride, a road trip you never forgot?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And since we're all developers here, one more:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your favorite car were a piece of software, what would it be?&lt;/strong&gt;&lt;br&gt;
My Urus is a monolith that somehow scales and still ships features nobody expected. A vintage Beetle? That's a bash script that has somehow run in production for 30 years. A Tesla? Obviously a startup that ships OTA updates every week. 😂&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 And if you tried ATLOCK v5...
&lt;/h2&gt;

&lt;p&gt;I'd genuinely love your feedback. Tell me what's confusing, what's missing, what you'd want next. I read everything. A tool like this only gets better when people try to break it, question it, and tell me where the lock has a weak spot.&lt;/p&gt;

&lt;p&gt;That's how every great car got better, too. One test track at a time.&lt;/p&gt;

&lt;p&gt;So: &lt;strong&gt;what's your car, and why?&lt;/strong&gt; 👇&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let's make this the best comment section on dev.to.&lt;/em&gt; &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
      <category>security</category>
      <category>python</category>
    </item>
    <item>
      <title>I'm 13. I built a 10,000-line security suite for Windows. Meet ATLOCK v5.</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Mon, 12 Oct 2026 10:03:26 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/im-13-i-built-a-10000-line-security-suite-for-windows-meet-atlock-v5-eh8</link>
      <guid>https://dev.to/akhourianmolkumar/im-13-i-built-a-10000-line-security-suite-for-windows-meet-atlock-v5-eh8</guid>
      <description>&lt;p&gt;Description: "ATLOCK v5 by Akhouri Systems: Argon2id + AES-256-GCM encryption, a decoy vault, FIDO2, ransomware canaries, Shamir recovery, and a self-verifying release. Here's how it works."&lt;/p&gt;

&lt;h1&gt;
  
  
  ATLOCK v5 is out. 🔐
&lt;/h1&gt;

&lt;p&gt;Some people say &lt;em&gt;"Akhouri Systems has never built a serious app."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From today, I have a one-word reply:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;ATLOCK_v5&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Hey dev.to 👋 I'm &lt;strong&gt;Anmol&lt;/strong&gt;, founder of &lt;strong&gt;Akhouri Systems&lt;/strong&gt;. I'm &lt;strong&gt;13&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I'm not telling you my age for sympathy points. I'm telling you because I want you to judge the &lt;strong&gt;app&lt;/strong&gt;, not the birth certificate. So here it is:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK/releases/download/v5.0.0/ATLOCK_v5.zip" rel="noopener noreferrer"&gt;Download ATLOCK v5&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is ATLOCK?
&lt;/h2&gt;

&lt;p&gt;ATLOCK is a &lt;strong&gt;Windows-first total security suite&lt;/strong&gt;, shipped as a &lt;strong&gt;.exe&lt;/strong&gt; and written in &lt;strong&gt;pure Python&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Module&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🗄️ &lt;strong&gt;File Guard&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Encrypt files and whole folders with a password (plus optional keyfile / hardware key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔑 &lt;strong&gt;Password Vault&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Offline vault with a &lt;strong&gt;decoy "panic" mode&lt;/strong&gt;, breach checks, and importers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚡ &lt;strong&gt;Quick Lock&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;One-click locking from the Explorer right-click menu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🛡️ &lt;strong&gt;Defender Dashboard&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Security overview, VirusTotal integration, startup watchdog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🐤 &lt;strong&gt;Ransomware Canary&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Tripwire files that detect suspicious tampering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧰 &lt;strong&gt;CLI toolbox&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;50+ command-line flags for power users&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The app runs exactly as you'd expect with no arguments, and the CLI is there if you want to go deep.&lt;/p&gt;




&lt;h2&gt;
  
  
  The architecture, in one picture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        ┌────────────── ATLOCK v5 ──────────────┐
        │   Tkinter UI  ·  CLI (--flags)        │
        ├───────────────────────────────────────┤
        │ File Guard │ Vault │ Quick Lock       │
        │ Defender   │ Canary│ Watchdog         │
        ├───────────────────────────────────────┤
        │  2FA: TOTP · FIDO2 · Windows Hello    │
        ├───────────────────────────────────────┤
        │  Sealed State (AES-GCM + HMAC anchors)│
        ├───────────────────────────────────────┤
        │  Crypto core: Argon2id → HKDF →       │
        │  chunked AES-256-GCM (v3.1 container) │
        └───────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔬 The nerdy part (my favorite)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Container format v3.1: built like a real crypto format
&lt;/h3&gt;

&lt;p&gt;Every locked file, folder, and Quick Lock item uses my own container format:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chunked AES-256-GCM&lt;/strong&gt;: each chunk is authenticated independently, so one corrupted chunk doesn't mean a lost file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key commitment&lt;/strong&gt;: a wrong password is detected &lt;em&gt;before any plaintext is produced&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-seal chunk subkeys&lt;/strong&gt; derived with HKDF&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header-bound AAD&lt;/strong&gt;: tamper with the header and decryption fails&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Padme padding&lt;/strong&gt; &lt;em&gt;(optional)&lt;/em&gt;: hides the true file size, with at most ~12% overhead&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backward compatible&lt;/strong&gt;: v1/v2 containers and old 5.0 files still open and migrate automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Argon2id everywhere (and a safety ceiling)
&lt;/h3&gt;

&lt;p&gt;Passwords are stretched with &lt;strong&gt;Argon2id&lt;/strong&gt;, at a &lt;strong&gt;64 MB / t=3 floor&lt;/strong&gt; for files and &lt;strong&gt;128 MB / t=4&lt;/strong&gt; for the vault and recovery keys.&lt;/p&gt;

&lt;p&gt;The part I'm proud of: &lt;strong&gt;untrusted headers can't abuse the KDF.&lt;/strong&gt; If someone hands you a doctored file claiming "use 40 GB of RAM," ATLOCK refuses. There's a hard ceiling (512 MB, t=6, p=8), so a malicious file can't freeze your PC.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The panic password (decoy vault) 🎭
&lt;/h3&gt;

&lt;p&gt;The vault has &lt;strong&gt;two passwords&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your &lt;strong&gt;real&lt;/strong&gt; master password&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;panic password&lt;/strong&gt; that opens a believable, &lt;strong&gt;entirely fake&lt;/strong&gt; vault&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the clever bit: both slots are derived &lt;strong&gt;concurrently&lt;/strong&gt; with the same KDF cost, so an observer can't tell which password you typed by timing it. And the decoy slot &lt;strong&gt;always exists&lt;/strong&gt;, filled with random bytes if you never set one, so the file itself never reveals whether you use panic mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Real second factors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TOTP&lt;/strong&gt; (RFC 6238), implemented in pure Python 🐍&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FIDO2 / WebAuthn&lt;/strong&gt; hardware keys (YubiKey etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows Hello&lt;/strong&gt; (face / fingerprint / PIN)&lt;/li&gt;
&lt;li&gt;Fail-closed policy: if your policy &lt;em&gt;requires&lt;/em&gt; a second factor and it isn't set up, access is &lt;strong&gt;denied&lt;/strong&gt;, not skipped&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Anti-rollback sealed state
&lt;/h3&gt;

&lt;p&gt;Settings, vault data, lockout counters, watchdog and canary databases all live in &lt;strong&gt;sealed state&lt;/strong&gt;: AES-256-GCM encrypted, HMAC-authenticated, protected by a Windows DPAPI-wrapped key, and &lt;strong&gt;rollback-anchored&lt;/strong&gt;. If an attacker restores an old copy to reset your wrong-password counter, ATLOCK notices and &lt;strong&gt;hard-locks&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Breach checks without leaking your password
&lt;/h3&gt;

&lt;p&gt;The vault audits for &lt;strong&gt;weak, reused, old, and breached&lt;/strong&gt; passwords. The breach check uses &lt;strong&gt;HIBP k-anonymity&lt;/strong&gt;: only a &lt;strong&gt;5-character hash prefix&lt;/strong&gt; ever leaves your machine, never the password.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Clipboard that doesn't snitch
&lt;/h3&gt;

&lt;p&gt;Copied passwords are flagged so Windows &lt;strong&gt;excludes them from clipboard history and cloud clipboard sync&lt;/strong&gt;, then cleared automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Hardened against nasty files
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Folder locking uses a &lt;strong&gt;hardened ZIP&lt;/strong&gt; pipeline that defends against &lt;strong&gt;zip-slip, path traversal, symlink tricks, and zip bombs&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DLL-planting defence&lt;/strong&gt; runs &lt;em&gt;before any other import&lt;/em&gt; loads a DLL&lt;/li&gt;
&lt;li&gt;All data is &lt;strong&gt;ACL-restricted to your Windows user&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SecureBuffer&lt;/code&gt; + &lt;code&gt;VirtualLock&lt;/code&gt; + zeroing for secrets in memory, best-effort (see the honesty section)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9. Recovery done right
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shamir secret sharing&lt;/strong&gt;: split a recovery key into shares and rebuild it from enough of them (&lt;code&gt;--shamir-split&lt;/code&gt; / &lt;code&gt;--shamir-join&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;One-time recovery codes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Forgot the master password? &lt;code&gt;--reset&lt;/code&gt; queues a reset that completes after &lt;strong&gt;24 hours&lt;/strong&gt;, and any successful unlock cancels it, so an attacker can't instantly take over&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10. In v5: stuff I'm really proud of
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--getting-started&lt;/span&gt;        &lt;span class="c"&gt;# plain-language quick start + glossary&lt;/span&gt;
&lt;span class="nt"&gt;--device-health&lt;/span&gt;          &lt;span class="c"&gt;# BitLocker / hibernation / cloud-folder check&lt;/span&gt;
&lt;span class="nt"&gt;--keyfile-create&lt;/span&gt; PATH    &lt;span class="c"&gt;# strong keyfile for File Guard&lt;/span&gt;
&lt;span class="nt"&gt;--wipe-free-space&lt;/span&gt;        &lt;span class="c"&gt;# overwrite free disk space&lt;/span&gt;
&lt;span class="nt"&gt;--fuzz&lt;/span&gt; 300               &lt;span class="c"&gt;# stress-test the container parser with 300 random corruptions&lt;/span&gt;
&lt;span class="nt"&gt;--pk-keygen&lt;/span&gt; / &lt;span class="nt"&gt;--pk-encrypt&lt;/span&gt; / &lt;span class="nt"&gt;--pk-decrypt&lt;/span&gt; / &lt;span class="nt"&gt;--sign&lt;/span&gt; / &lt;span class="nt"&gt;--check-sig&lt;/span&gt;   &lt;span class="c"&gt;# public-key crypto&lt;/span&gt;
&lt;span class="nt"&gt;--verify-self&lt;/span&gt;            &lt;span class="c"&gt;# signed-release self check&lt;/span&gt;
&lt;span class="nt"&gt;--import-passwords&lt;/span&gt; FILE  &lt;span class="c"&gt;# Bitwarden / Chrome / Firefox / KeePass / 1Password&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, ATLOCK ships with &lt;strong&gt;its own fuzzer&lt;/strong&gt; and &lt;strong&gt;a self-test&lt;/strong&gt; (&lt;code&gt;--selftest&lt;/code&gt;). I wanted it to attack itself before anyone else does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extra lock:&lt;/strong&gt; in File Guard you can require &lt;strong&gt;both&lt;/strong&gt; your password &lt;strong&gt;and&lt;/strong&gt; a keyfile or hardware key, so a stolen password alone isn't enough.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Honest limits (the part most projects skip)
&lt;/h2&gt;

&lt;p&gt;Real security engineers respect honesty more than hype, so here's what ATLOCK &lt;strong&gt;cannot&lt;/strong&gt; do. This is also written into the source code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A same-user attacker who can run code &lt;em&gt;as you&lt;/em&gt; can modify the program or its files, or read process memory. Integrity checks and anti-debug raise the cost, but they don't make it impossible.&lt;/li&gt;
&lt;li&gt;Python strings are immutable, so passwords can't be &lt;em&gt;guaranteed&lt;/em&gt; erased from RAM.&lt;/li&gt;
&lt;li&gt;Secure shredding on SSDs isn't guaranteed. &lt;strong&gt;BitLocker is the real fix&lt;/strong&gt;, and &lt;code&gt;--device-health&lt;/code&gt; checks for it.&lt;/li&gt;
&lt;li&gt;No kernel driver and &lt;strong&gt;no code signing&lt;/strong&gt;. ATLOCK is an application-layer tool, so Windows SmartScreen may show a warning the first time you run it. Check the SHA-256 below before you run it.&lt;/li&gt;
&lt;li&gt;FIDO2 here proves the registered key was present and touched. It doesn't validate the vendor.&lt;/li&gt;
&lt;li&gt;The real defence against offline guessing is &lt;strong&gt;Argon2id + a genuinely strong password&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd rather you trust ATLOCK for what it &lt;em&gt;is&lt;/em&gt; than be fooled by what it isn't.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Get started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Download and extract &lt;strong&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK/releases/download/v5.0.0/ATLOCK_v5.zip" rel="noopener noreferrer"&gt;ATLOCK_v5.zip&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;ATLOCK_v5.exe&lt;/code&gt;. New here? Try &lt;code&gt;ATLOCK_v5.exe --getting-started&lt;/code&gt; first.(when you run ATLOCK_v5 first time it will automatically show the guide) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⭐ &lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK" rel="noopener noreferrer"&gt;github.com/Akhouri-Anmol-Kumar/ATLOCK&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I built this
&lt;/h2&gt;

&lt;p&gt;I didn't want to build another to-do app to prove I could code. I wanted to build something where &lt;strong&gt;every design decision has a reason&lt;/strong&gt;, a tool I'd trust with my &lt;em&gt;own&lt;/em&gt; files, and one I could defend line by line.&lt;/p&gt;

&lt;p&gt;Hype lasts a week, but &lt;strong&gt;work that holds up&lt;/strong&gt; lasts years. That's why ATLOCK has versioned formats, automatic migrations, a self-test, a fuzzer, and a page of honest limitations.&lt;/p&gt;

&lt;p&gt;Akhouri Systems is just getting started. ATLOCK v5 is proof of what we can build, and it's the &lt;strong&gt;floor&lt;/strong&gt; of what's coming, not the ceiling.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 Your turn, dev.to
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Break it. Run &lt;code&gt;ATLOCK_v5.exe --fuzz&lt;/code&gt;, read the container format, try to find a flaw.&lt;/li&gt;
&lt;li&gt;Open an issue or PR. I read every one.&lt;/li&gt;
&lt;li&gt;Tell me what v6 should have. No promises on timing, though. I'm pretty exhausted after this one 😅&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm 13, I'm just getting started, and this is v5. 😉&lt;/p&gt;

&lt;p&gt;— &lt;strong&gt;Anmol Kumar Akhouri&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Founder, Akhouri Systems&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built with Python, tkinter, &lt;code&gt;cryptography&lt;/code&gt;, and &lt;code&gt;argon2-cffi&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>security</category>
      <category>showdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Switched to Brave and Never Looked Back. Change My Mind. 🦁 (Which Browser Do YOU Use, and WHY?)</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Sat, 10 Oct 2026 08:43:08 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/i-switched-to-brave-and-never-looked-back-change-my-mind-which-browser-do-you-use-and-why-2npa</link>
      <guid>https://dev.to/akhourianmolkumar/i-switched-to-brave-and-never-looked-back-change-my-mind-which-browser-do-you-use-and-why-2npa</guid>
      <description>&lt;p&gt;Description: "100M+ people use Brave every month. Is it the best browser for developers, or am I in a cult? Tell me your browser and defend it in the comments."&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's start with a confession 🙈
&lt;/h2&gt;

&lt;p&gt;I have &lt;strong&gt;40+ tabs open right now&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Docs. Stack Overflow. GitHub. A YouTube video I'll "watch later" (I won't). Three tutorials I opened to "quickly check something" two hours ago. And a localhost project that has been broken since Tuesday.&lt;/p&gt;

&lt;p&gt;If my browser were a person, it would be asking for a raise, a vacation, and probably a therapist.&lt;/p&gt;

&lt;p&gt;So today I want to ask the question every developer secretly has a &lt;em&gt;very&lt;/em&gt; strong opinion about:&lt;/p&gt;

&lt;h1&gt;
  
  
  🌐 Which browser are you using, and WHY?
&lt;/h1&gt;

&lt;p&gt;Not "which one is popular."&lt;br&gt;
Not "which one came pre-installed."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which one would you defend at 2 AM in a comment section?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's my answer first. Then it's your turn. 👇&lt;/p&gt;


&lt;h2&gt;
  
  
  📜 A 60-second history of why we're even having this argument
&lt;/h2&gt;

&lt;p&gt;Browsers have been fighting since before some of you were born:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The 90s:&lt;/strong&gt; Netscape and Internet Explorer go to war. The web becomes a battlefield.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2004:&lt;/strong&gt; Firefox shows up and reminds everyone that browsers can be good.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2008:&lt;/strong&gt; Chrome launches, and "fast and simple" becomes the new standard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2016:&lt;/strong&gt; Brave appears, co-founded by &lt;strong&gt;Brendan Eich, the person who created JavaScript&lt;/strong&gt;. Yes, the same person. The guy who gave us &lt;code&gt;[] + {}&lt;/code&gt; also gave us a privacy-first browser. 😂&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2020:&lt;/strong&gt; Edge switches to Chromium, and suddenly "Microsoft's browser" is a serious option.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Today:&lt;/strong&gt; Most of the web runs on Chromium, with Firefox and Safari holding the line as the other engines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every browser on this list exists because someone looked at the existing options and said, &lt;em&gt;"I can do this better."&lt;/em&gt; I love that. It's also why this discussion never ends.&lt;/p&gt;


&lt;h2&gt;
  
  
  🦁 I use Brave. Here's the honest case.
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. The ad blocker is built in, and for me it's the best I've used
&lt;/h3&gt;

&lt;p&gt;No extension to install. No extension to update. No extension asking permission to "read and change all your data on all websites" (which, let's be honest, should make us all a little nervous).&lt;/p&gt;

&lt;p&gt;Brave Shields works from the first launch. It blocks ads and trackers, and it upgrades connections to HTTPS where it can. Pages load faster, the clutter disappears, and I stopped feeling like I was reading the internet through a casino window.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My honest take, not a lab benchmark: after Brave, going back to a browser full of ads feels like going back to dial-up. 😅&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can tune it &lt;strong&gt;per site&lt;/strong&gt;. Click the lion icon in the address bar and you get a dashboard of what was blocked on that page. The first time you see the number on a news site, you will not be okay. 😳&lt;/p&gt;
&lt;h3&gt;
  
  
  2. It feels lighter on RAM
&lt;/h3&gt;

&lt;p&gt;Every dev knows the moment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a few tabs.&lt;/li&gt;
&lt;li&gt;Hear the laptop fan start to sound like a jet engine.&lt;/li&gt;
&lt;li&gt;Check the task manager.&lt;/li&gt;
&lt;li&gt;Watch your browser casually eating gigabytes like it's a buffet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On my machine, Brave with an unreasonable number of tabs feels noticeably smoother. Less junk loading (ads, trackers, auto-playing nonsense) means less junk running in the background. Your mileage may vary, so tell me if yours is different. I actually want to know. (More on that in a minute. 👀)&lt;/p&gt;
&lt;h3&gt;
  
  
  3. The cult following is real 🔥
&lt;/h3&gt;

&lt;p&gt;Brave now has &lt;strong&gt;over 100 million monthly active users&lt;/strong&gt;. That's not a niche browser anymore. That's a movement.&lt;/p&gt;

&lt;p&gt;And Brave people are &lt;em&gt;loud&lt;/em&gt; about it. Ask one why they use Brave and you'll get a TED Talk. (Guilty. 🙋 I'm literally writing one right now.)&lt;/p&gt;
&lt;h3&gt;
  
  
  4. It's Chromium under the hood, so my dev life barely changes
&lt;/h3&gt;

&lt;p&gt;Chrome DevTools? Same familiar feel. Chrome Web Store extensions? They work. Switching didn't mean relearning my whole workflow. I got the privacy upgrade without the productivity downgrade.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. The extras you didn't know you wanted
&lt;/h3&gt;

&lt;p&gt;Built into the browser, no setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🕵️ &lt;strong&gt;Private windows with Tor&lt;/strong&gt; for extra anonymity when you need it&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Brave Search&lt;/strong&gt;, an independent search option&lt;/li&gt;
&lt;li&gt;🤖 &lt;strong&gt;Leo&lt;/strong&gt;, a built-in AI assistant&lt;/li&gt;
&lt;li&gt;🧰 Fingerprinting protection and cookie controls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not everyone will use all of it. But having it there is a very different feeling from hunting for five separate extensions.&lt;/p&gt;


&lt;h2&gt;
  
  
  😬 Okay, but let's be fair: the "Brave isn't perfect" section
&lt;/h2&gt;

&lt;p&gt;I don't trust anyone who says their favorite tool has zero flaws. So here's the honest list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Crypto and rewards features aren't for everyone.&lt;/strong&gt; They're optional and you can turn them off, but some people find them distracting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Past controversies exist.&lt;/strong&gt; Brave has had a few over the years, and if trust matters to you (it should), read up and decide for yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shields can break some sites.&lt;/strong&gt; A login or video player occasionally misbehaves until you lower the shield for that site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chromium dominance is a real concern.&lt;/strong&gt; Whichever Chromium browser we pick, we're all feeding the same engine monoculture. Firefox users have a point here, and I respect it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd rather you hear it from me than think I'm selling you something. Still Brave for me, but with my eyes open. 👀&lt;/p&gt;


&lt;h2&gt;
  
  
  📊 The Developer Browser Tier List (Fight Me)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Browser&lt;/th&gt;
&lt;th&gt;Why devs love it&lt;/th&gt;
&lt;th&gt;Why devs rage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Brave&lt;/strong&gt; 🦁&lt;/td&gt;
&lt;td&gt;Built-in blocker, privacy, Chromium DevTools&lt;/td&gt;
&lt;td&gt;Some sites get fussy with Shields on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chrome&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DevTools, extensions, everything just works&lt;/td&gt;
&lt;td&gt;Hungry for RAM, hungry for data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Firefox&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Independent engine, privacy, great CSS tools&lt;/td&gt;
&lt;td&gt;Some sites only get tested on Chromium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Edge&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fast, smooth, surprisingly good&lt;/td&gt;
&lt;td&gt;"Why is there a shopping tab?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Safari&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Battery life, great on Apple hardware&lt;/td&gt;
&lt;td&gt;Testing on it is its own personality test&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Disagree with the table? &lt;strong&gt;Good. That's literally what the comments are for.&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%2Fwxk3k9exid290fbxge7j.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%2Fwxk3k9exid290fbxge7j.png" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🎭 What your browser says about you (100% scientific, 0% accurate)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🦁 &lt;strong&gt;Brave:&lt;/strong&gt; Reads privacy policies for fun. Has opinions about trackers. Will mention it at parties.&lt;/li&gt;
&lt;li&gt;🟡 &lt;strong&gt;Chrome:&lt;/strong&gt; "It just works." Has 87 extensions and no idea what 60 of them do.&lt;/li&gt;
&lt;li&gt;🦊 &lt;strong&gt;Firefox:&lt;/strong&gt; Loyal. Principled. Has been defending Firefox since 2009 and is not tired.&lt;/li&gt;
&lt;li&gt;🔷 &lt;strong&gt;Edge:&lt;/strong&gt; Quiet confidence. Knows it's good. Tired of being the punchline.&lt;/li&gt;
&lt;li&gt;🧭 &lt;strong&gt;Safari:&lt;/strong&gt; Lives in the Apple ecosystem and is happy there. Do not disturb.&lt;/li&gt;
&lt;li&gt;🕵️ &lt;strong&gt;Tor Browser:&lt;/strong&gt; You don't tell anyone. You just &lt;em&gt;know&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I got yours wrong, tell me. If I got it painfully right, tell me that too. 😂&lt;/p&gt;


&lt;h2&gt;
  
  
  🧪 The Tab Challenge: Let's settle the RAM debate with real data
&lt;/h2&gt;

&lt;p&gt;I don't want you to just take my word for it. Let's test it. Takes 3 minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Close everything except your browser.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;same 10 tabs&lt;/strong&gt; in each browser you use (same sites, same order).&lt;/li&gt;
&lt;li&gt;Wait about a minute for everything to settle.&lt;/li&gt;
&lt;li&gt;Open your &lt;strong&gt;Task Manager&lt;/strong&gt; (Windows) or &lt;strong&gt;Activity Monitor&lt;/strong&gt; (Mac) and check the browser's total memory.&lt;/li&gt;
&lt;li&gt;Come back and &lt;strong&gt;post your result in the comments&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use this format so we can compare:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Browser:&lt;/strong&gt; ___ | &lt;strong&gt;OS:&lt;/strong&gt; ___ | &lt;strong&gt;Same 10 tabs:&lt;/strong&gt; ___ GB&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If enough people join, I'll collect the results in a follow-up post. Real numbers from real dev machines, no marketing. 📊&lt;/p&gt;

&lt;p&gt;(And if Brave loses on your machine, I want to see that too. Honesty gets more respect than fanboying.)&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ 5 DevTools tricks I wish I'd known years earlier
&lt;/h2&gt;

&lt;p&gt;Since this is dev.to, here's some actual value. These work in any Chromium-based browser, Brave included. Save this post. 😉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The command menu.&lt;/strong&gt; Open DevTools, then press &lt;code&gt;Ctrl + Shift + P&lt;/code&gt; (&lt;code&gt;Cmd + Shift + P&lt;/code&gt; on Mac). You can type almost anything: "screenshot", "dark theme", "disable cache". It's like a search bar for DevTools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Full-page screenshots without an extension.&lt;/strong&gt; In that same command menu, type &lt;code&gt;screenshot&lt;/code&gt; and pick &lt;strong&gt;Capture full size screenshot&lt;/strong&gt;. Boom, the whole page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. &lt;code&gt;$0&lt;/code&gt; in the console.&lt;/strong&gt; Select an element in the Elements panel, then type &lt;code&gt;$0&lt;/code&gt; in the console. You now have a live reference to it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. &lt;code&gt;console.table()&lt;/code&gt; for readable data.&lt;/strong&gt; Stop squinting at nested JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Brave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ram&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;happy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Other&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ram&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crying&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Network throttling.&lt;/strong&gt; Open the Network tab and set throttling to "Slow 4G". Suddenly you can feel what your users on bad connections feel. It's humbling. 🥲&lt;/p&gt;

&lt;p&gt;Got a better trick? &lt;strong&gt;Drop it in the comments.&lt;/strong&gt; The best ones go in my notes, and I'll credit you.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Plot twist: building for the browser changed how I see browsers
&lt;/h2&gt;

&lt;p&gt;Once I started building tools &lt;em&gt;for&lt;/em&gt; the browser, I stopped seeing it as a window to the internet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's a runtime now.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I build under &lt;strong&gt;Akhouri Systems&lt;/strong&gt;, and one of my projects is &lt;strong&gt;APIC (Advanced Image Processing Center)&lt;/strong&gt;. It began as a desktop app in Python and PyQt6 with Edit, Convert, Compress, Search and batch processing. Then I had a question that wouldn't leave me alone:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Could this live entirely inside a browser tab?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It could. Today the web version does all of this &lt;strong&gt;inside the tab&lt;/strong&gt;, with no server round trip for your images:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎨 &lt;strong&gt;Edit&lt;/strong&gt; with filters like Cyberpunk, Sepia, Noir and Cold Chrome, plus levels, gamma, sharpen, temperature and vignette&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Convert&lt;/strong&gt; between PNG, JPEG, WebP, BMP, ICO and PDF&lt;/li&gt;
&lt;li&gt;📉 &lt;strong&gt;Compress&lt;/strong&gt; to a target file size by searching for the best quality that still fits&lt;/li&gt;
&lt;li&gt;✂️ &lt;strong&gt;Remove backgrounds&lt;/strong&gt; with on-device AI&lt;/li&gt;
&lt;li&gt;🪄 &lt;strong&gt;Remove objects&lt;/strong&gt; using an inpainting model (MI-GAN) running through WebAssembly&lt;/li&gt;
&lt;li&gt;📐 &lt;strong&gt;Resize&lt;/strong&gt; with step-down resampling, so results stay crisp instead of muddy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your image never leaves your device. A browser that respects your privacy plus a tool that respects your privacy turns out to be a really good combination, and that's a big reason I care about this whole topic.&lt;/p&gt;

&lt;p&gt;👉 Try it here: &lt;strong&gt;&lt;a href="https://apicweb.vercel.app/" rel="noopener noreferrer"&gt;APIC Web&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Honestly, the weirdest part of this project was realizing how much a modern browser can do &lt;strong&gt;without a backend&lt;/strong&gt;: canvas, WebAssembly, on-device ML models, file downloads. Ten years ago this would have needed a server farm. Now it's a tab. That alone makes me excited to be a dev in 2026.&lt;/p&gt;

&lt;p&gt;It also changed how I test. Every feature I built had to be checked in multiple browsers, because &lt;em&gt;"works in my browser"&lt;/em&gt; is the most dangerous sentence in web development. Brave with Shields on is actually a great stress test: if your app survives an aggressive blocker, it's more robust for everyone.&lt;/p&gt;

&lt;p&gt;And if you're the "I want it on my desk, offline" type, there's a desktop build too:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/APIC/releases/download/APIC/APIC.zip" rel="noopener noreferrer"&gt;APIC for Windows (.zip, no account needed)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If something breaks, tell me in the comments. I read every single one. 🙏&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 Thinking of switching? Here's how to do it without pain
&lt;/h2&gt;

&lt;p&gt;If this post made you curious, here's the easy way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the new browser&lt;/strong&gt; and keep your old one for a week. No pressure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Import your bookmarks and passwords.&lt;/strong&gt; Most browsers have a one-click import.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sign back into your extensions&lt;/strong&gt; and see which ones you actually need. (You'll be surprised how many you don't.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use it for real work for 7 days.&lt;/strong&gt; Not just casual browsing, your actual daily workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compare.&lt;/strong&gt; Speed, battery, RAM, how you &lt;em&gt;feel&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you hate it, switch back. Zero shame. The best browser is the one that makes &lt;strong&gt;you&lt;/strong&gt; more productive.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ Lightning Round: answer in one word
&lt;/h2&gt;

&lt;p&gt;Reply to this post with just one word for each:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Best browser for developers?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best browser for privacy?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best browser for battery life?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Most overrated browser?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser you secretly use but won't admit?&lt;/strong&gt; 🤫&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Short answers, long arguments. Let's go.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 Unpopular opinions corner
&lt;/h2&gt;

&lt;p&gt;I'll start with mine. Come argue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"Most people don't need 20 extensions. They need a better browser."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"If your site breaks with an ad blocker on, that's a design problem, not a user problem."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Tab hoarding is a personality, not a bug."&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now post &lt;strong&gt;your&lt;/strong&gt; unpopular browser opinion below. The spicier the better, and I promise to reply with respect even if I disagree. 🤝&lt;/p&gt;




&lt;h2&gt;
  
  
  🎤 Now it's YOUR turn
&lt;/h2&gt;

&lt;p&gt;Drop your answers below. I want the real ones, not the polite ones:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;🌐 &lt;strong&gt;What's your main browser, and what's the ONE reason you'd never switch?&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;💀 &lt;strong&gt;What's the browser feature you'd fight to keep?&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;😤 &lt;strong&gt;What's the dumbest thing your browser has ever done to you?&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🔥 &lt;strong&gt;Hot take: which browser is overrated?&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;What's the one extension you can't live without?&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🗳️ Vote with an emoji in the comments:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🦁 = Brave&lt;/li&gt;
&lt;li&gt;🟡 = Chrome&lt;/li&gt;
&lt;li&gt;🦊 = Firefox&lt;/li&gt;
&lt;li&gt;🔷 = Edge&lt;/li&gt;
&lt;li&gt;🧭 = Safari&lt;/li&gt;
&lt;li&gt;🎭 = "Other, let me explain..."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll count the votes and post the &lt;strong&gt;official dev.to browser results&lt;/strong&gt; in a follow-up. 📊&lt;/p&gt;




&lt;h2&gt;
  
  
  🏆 The Comment Challenge
&lt;/h2&gt;

&lt;p&gt;Copy this and fill it in. It takes 10 seconds:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;My browser:&lt;/strong&gt; ___&lt;br&gt;
&lt;strong&gt;Why I'll never switch:&lt;/strong&gt; ___&lt;br&gt;
&lt;strong&gt;My hottest browser take:&lt;/strong&gt; ___&lt;br&gt;
&lt;strong&gt;Tabs open right now:&lt;/strong&gt; ___&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm going first: &lt;strong&gt;Brave / the built-in blocker / "RAM usage is a feature" / 43.&lt;/strong&gt; 😅&lt;/p&gt;

&lt;p&gt;Beat my tab count and you win. Nothing, except pride and my eternal respect.&lt;/p&gt;




&lt;h2&gt;
  
  
  💎 If this made you laugh, nod, or want to argue
&lt;/h2&gt;

&lt;p&gt;Hit the ❤️, drop a 🦄, and &lt;strong&gt;tell me why my browser is wrong&lt;/strong&gt;. The best comment gets a detailed reply from me, and the funniest one gets a follow.&lt;/p&gt;

&lt;p&gt;See you in the comments. Bring your hot takes. 🔥&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which browser are you using, and WHY?&lt;/strong&gt; 👇&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. If you read this far with 30 tabs open, you're my kind of person. Please close at least 10 of them. I won't.&lt;/em&gt; 😄&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.P.S. Found a bug in APIC, or have a feature idea? Put it in the comments. Half of the best features in any project come from people who weren't afraid to say "hey, what if...?"&lt;/em&gt; 💡&lt;/p&gt;

</description>
      <category>browser</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I'm 13 and I Built a Security Suite. So... Does Age Really Matter?</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Fri, 09 Oct 2026 11:23:00 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/im-13-and-i-built-a-security-suite-so-does-age-really-matter-3boo</link>
      <guid>https://dev.to/akhourianmolkumar/im-13-and-i-built-a-security-suite-so-does-age-really-matter-3boo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I'm 13. I built &lt;strong&gt;ATLOCK v5&lt;/strong&gt;, a full security suite in Python. Nobody asked my age when I typed &lt;code&gt;pip install&lt;/code&gt;, and the compiler never asked either. So let's talk about whether age &lt;em&gt;really&lt;/em&gt; matters. 👇&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The question nobody asks out loud
&lt;/h2&gt;

&lt;p&gt;Every time someone finds out I'm 13, the conversation changes.&lt;/p&gt;

&lt;p&gt;Before they know: &lt;em&gt;"Interesting project. How does the encryption work?"&lt;/em&gt;&lt;br&gt;
After they know: &lt;em&gt;"Wow, that's so cute! Did your dad help?"&lt;/em&gt; 🙃(and for akhouri systems my dad is the biggest enemy) &lt;/p&gt;

&lt;p&gt;Same code. Same project. Different reaction. The only thing that changed was a number.&lt;/p&gt;

&lt;p&gt;So I want to ask this honestly, and I want &lt;strong&gt;you&lt;/strong&gt; to answer honestly:&lt;/p&gt;
&lt;h1&gt;
  
  
  Does age really matter?
&lt;/h1&gt;


&lt;h2&gt;
  
  
  Quick intro (I'll keep it short, I promise)
&lt;/h2&gt;

&lt;p&gt;I'm &lt;strong&gt;Anmol&lt;/strong&gt;, I'm &lt;strong&gt;13&lt;/strong&gt;, and I run &lt;strong&gt;Akhouri Systems&lt;/strong&gt;, a tiny one-person software company where I build things that probably shouldn't be built by someone who still has homework.(😂☠️🔥)&lt;/p&gt;

&lt;p&gt;My biggest project is &lt;strong&gt;ATLOCK&lt;/strong&gt;, a security suite written in Python. Version 5 is now &lt;strong&gt;9,000+ lines&lt;/strong&gt; of code(it was peaked 10870+ lines but somehow I removed the useless stuffs), and here's what's inside:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔐 &lt;strong&gt;AES-256-GCM&lt;/strong&gt; encrypted containers with key commitment&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Argon2id&lt;/strong&gt; password hashing, so brute-forcing hurts&lt;/li&gt;
&lt;li&gt;🗝️ A &lt;strong&gt;password vault&lt;/strong&gt; with 2FA (TOTP) support&lt;/li&gt;
&lt;li&gt;🎭 A &lt;strong&gt;panic password&lt;/strong&gt; that opens a &lt;em&gt;decoy&lt;/em&gt; vault instead of your real one&lt;/li&gt;
&lt;li&gt;⏳ &lt;strong&gt;Smart lockouts&lt;/strong&gt; with exponential backoff that resist clock tampering&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Shamir secret sharing&lt;/strong&gt; to split recovery keys&lt;/li&gt;
&lt;li&gt;🛡️ Optional &lt;strong&gt;TPM-backed&lt;/strong&gt; key protection and Windows Hello support&lt;/li&gt;
&lt;li&gt;🔎 &lt;strong&gt;Breach checks&lt;/strong&gt; that never send your password anywhere (k-anonymity)&lt;/li&gt;
&lt;li&gt;🧪 A built-in &lt;strong&gt;fuzz self-test&lt;/strong&gt;, because I break my own code before you do&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll say the bold part out loud: &lt;strong&gt;I believe ATLOCK v5 is one of the greatest Python security suites ever built.&lt;/strong&gt; 😤 on planet earth 🌎&lt;/p&gt;

&lt;p&gt;Bold? Absolutely. So don't take my word for it. Try to break it. More on that below.&lt;/p&gt;


&lt;h2&gt;
  
  
  "But you're 13." Okay. Let's test that.
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;🧍 What people assume at 13&lt;/th&gt;
&lt;th&gt;🔧 What actually happened&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"You copied it from a tutorial."&lt;/td&gt;
&lt;td&gt;There's no tutorial for a decoy-vault, lockout-rollback, Shamir-split recovery suite. I read docs, broke things, and rebuilt them.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"You can't understand cryptography."&lt;/td&gt;
&lt;td&gt;I don't need to invent crypto. I need to &lt;em&gt;use&lt;/em&gt; it correctly, and that's a skill, not an age.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"It must be buggy."&lt;/td&gt;
&lt;td&gt;It &lt;em&gt;was&lt;/em&gt; buggy. I found and fixed rollback, timing, and lockout bugs. Every codebase has bugs. Age just gets blamed for mine.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"It's a school project."&lt;/td&gt;
&lt;td&gt;School doesn't assign this. Curiosity does.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Okay, but let's be honest: where age DOES matter
&lt;/h2&gt;

&lt;p&gt;I don't want to write a "kids are geniuses" post. That's lazy, and it's not true. Here's what age genuinely changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Experience.&lt;/strong&gt; I haven't seen a production system fail at 3 a.m. Older engineers have, and that scar tissue is real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Formal credentials.&lt;/strong&gt; No certifications, no independent security audit. ATLOCK has &lt;strong&gt;not&lt;/strong&gt; been audited by a third party yet. If that matters to you (and for security software it &lt;em&gt;should&lt;/em&gt;), I get it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time.&lt;/strong&gt; I build between school, exams and life. Progress is slower, not smaller.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trust.&lt;/strong&gt; People trust a name with a decade behind it faster than a name that's 13. Fair enough. Trust is earned.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But look at that list again. Every item is about &lt;strong&gt;experience, evidence and time&lt;/strong&gt;, not about the number itself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Age isn't the thing that matters. It's the thing people use because it's easier than checking the work.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A 40-year-old on day one of Python writes the same &lt;code&gt;NameError&lt;/code&gt; I did. A 13-year-old who's shipped for years has seen things. &lt;strong&gt;The calendar is a bad proxy for skill.&lt;/strong&gt; It's just an &lt;em&gt;easy&lt;/em&gt; one.&lt;/p&gt;


&lt;h2&gt;
  
  
  The part I need to say to the other side too
&lt;/h2&gt;

&lt;p&gt;Being young is &lt;strong&gt;not&lt;/strong&gt; a free pass.&lt;/p&gt;

&lt;p&gt;Please don't clap for ATLOCK &lt;em&gt;because&lt;/em&gt; I'm 13. That would be the exact opposite of what I'm arguing. It's &lt;strong&gt;security software&lt;/strong&gt;. If it's wrong, people lose data. So judge it the way you'd judge anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break the App(for now break v4 which is easy to break maybe 😂 but if you want to break harder ones then wait for ATLOCK v5) &lt;/li&gt;
&lt;li&gt;Open an issue. Tell me what's weak.&lt;/li&gt;
&lt;li&gt;If I'm wrong, say it. Politely or not, I'll read it either way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Respect the work, not the age. Criticize the work, not the age.&lt;/strong&gt; That's the whole deal.&lt;/p&gt;


&lt;h2&gt;
  
  
  Try ATLOCK (the old one) right now
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ATLOCK v5&lt;/strong&gt; is releasing on &lt;strong&gt;12 October&lt;/strong&gt;. 🚀&lt;br&gt;
Until then, you can try the previous version:&lt;/p&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/Akhouri-Anmol-Kumar" rel="noopener noreferrer"&gt;
        Akhouri-Anmol-Kumar
      &lt;/a&gt; / &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK" rel="noopener noreferrer"&gt;
        ATLOCK
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free Windows security suite — System Lockdown, File Guard, Password Vault.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK" rel="noopener noreferrer"&gt;
  &lt;img src="https://camo.githubusercontent.com/8fe36a975f88085bb95b55385f43825baf99dcddd7c6494c374c669afb860ee8/68747470733a2f2f726561646d652d747970696e672d7376672e64656d6f6c61622e636f6d3f666f6e743d5269676874656f75732673697a653d3535266475726174696f6e3d333030302670617573653d3135303026636f6c6f723d4339423937412663656e7465723d74727565267643656e7465723d747275652677696474683d363030266865696768743d3930266c696e65733d2546302539462539342539322b41544c4f434b3b544f54414c2b53454355524954592b5355495445" alt="ATLOCK"&gt;
&lt;/a&gt;
&lt;p&gt;&lt;strong&gt;The Total Security Suite for Windows.&lt;/strong&gt;
One &lt;code&gt;.exe&lt;/code&gt;. Zero installers. Zero compromises.&lt;/p&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/9ca8451ef455cc0533959e2f5c3888abe54772d6a58c5a69e16f84e82a54d719/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666f722d7468652d626164676526636f6c6f723d633962393761266c6162656c436f6c6f723d306130613061266c6162656c3d76657273696f6e"&gt;&lt;img src="https://camo.githubusercontent.com/9ca8451ef455cc0533959e2f5c3888abe54772d6a58c5a69e16f84e82a54d719/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666f722d7468652d626164676526636f6c6f723d633962393761266c6162656c436f6c6f723d306130613061266c6162656c3d76657273696f6e" alt="version"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/68af2c95607b1c04761f69856badfef63175fa7026e9b2db51d101fe17878390/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d57696e646f777325323031302532422d3461376162353f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d306130613061"&gt;&lt;img src="https://camo.githubusercontent.com/68af2c95607b1c04761f69856badfef63175fa7026e9b2db51d101fe17878390/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d57696e646f777325323031302532422d3461376162353f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d306130613061" alt="platform"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/14a0929aa2d6be0a6e2f6a006e80ff4cd7d2ed68158f93548e5b93595087de8b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666f722d7468652d626164676526636f6c6f723d346139653662266c6162656c436f6c6f723d306130613061"&gt;&lt;img src="https://camo.githubusercontent.com/14a0929aa2d6be0a6e2f6a006e80ff4cd7d2ed68158f93548e5b93595087de8b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666f722d7468652d626164676526636f6c6f723d346139653662266c6162656c436f6c6f723d306130613061" alt="license"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/fbe145d693c6493f921314c6366cb79d611375b98e01790e04474ec4c460aa70/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d616465253230696e2d496e6469612d3461396536623f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d306130613061"&gt;&lt;img src="https://camo.githubusercontent.com/fbe145d693c6493f921314c6366cb79d611375b98e01790e04474ec4c460aa70/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d616465253230696e2d496e6469612d3461396536623f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d306130613061" alt="made in India"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/278ae7a2767a94b65124cee5e546f289a52559a24ac0f112b3c8298b8bb936cf/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666c61742d73717561726526636f6c6f723d633962393761"&gt;&lt;img src="https://camo.githubusercontent.com/278ae7a2767a94b65124cee5e546f289a52559a24ac0f112b3c8298b8bb936cf/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666c61742d73717561726526636f6c6f723d633962393761" alt="stars"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/5a250205561e05e5315707b283e8e3e1b00dedd7a5b5ef27c124277e1161cb5f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b2f76342e302f746f74616c3f7374796c653d666c61742d73717561726526636f6c6f723d346137616235266c6162656c3d76342e30253230646f776e6c6f616473"&gt;&lt;img src="https://camo.githubusercontent.com/5a250205561e05e5315707b283e8e3e1b00dedd7a5b5ef27c124277e1161cb5f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b2f76342e302f746f74616c3f7374796c653d666c61742d73717561726526636f6c6f723d346137616235266c6162656c3d76342e30253230646f776e6c6f616473" alt="v4.0 downloads"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b110283f885620cc418e326e8083c758dd75d2228f597bda9962257d2f200f46/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666c61742d73717561726526636f6c6f723d346139653662"&gt;&lt;img src="https://camo.githubusercontent.com/b110283f885620cc418e326e8083c758dd75d2228f597bda9962257d2f200f46/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666c61742d73717561726526636f6c6f723d346139653662" alt="last commit"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/67d360df8ae26b21f45030dce617c446f945d1bb67d83f1aaecc3308a78af929/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666c61742d73717561726526636f6c6f723d633934613461"&gt;&lt;img src="https://camo.githubusercontent.com/67d360df8ae26b21f45030dce617c446f945d1bb67d83f1aaecc3308a78af929/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f416b686f7572692d416e6d6f6c2d4b756d61722f41544c4f434b3f7374796c653d666c61742d73717561726526636f6c6f723d633934613461" alt="issues"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK/releases/download/v4.0/ATLOCK.zip" rel="noopener noreferrer"&gt;&lt;br&gt;
  &lt;img src="https://camo.githubusercontent.com/0444c835c05dd766b47c1509bee9427d3f7957718ba2d6b8f699b967d17bed88/68747470733a2f2f696d672e736869656c64732e696f2f62616467652fe2ac87efb88f5f444f574e4c4f41445f41544c4f434b5f76342e302d6339623937613f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d306130613061266c6f676f436f6c6f723d7768697465" alt="Download ATLOCK v4.0" height="55"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Direct download · no sign-up · no ads&lt;/p&gt;



&lt;p&gt;
  &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-features" rel="noopener noreferrer"&gt;Features&lt;/a&gt; ·
  &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-installation" rel="noopener noreferrer"&gt;Installation&lt;/a&gt; ·
  &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-faq" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt; ·
  &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-roadmap" rel="noopener noreferrer"&gt;Roadmap&lt;/a&gt;
&lt;/p&gt;


&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/233440467/644436842-0c3e061f-b19f-4a43-856c-9618e4c8b83b.gif?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3OTE1NDUyODAsIm5iZiI6MTc5MTU0NDk4MCwicGF0aCI6Ii8yMzM0NDA0NjcvNjQ0NDM2ODQyLTBjM2UwNjFmLWIxOWYtNGE0My04NTZjLTk2MThlNGM4YjgzYi5naWY_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYxMDA5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MTAwOVQxMTIzMDBaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00YTQ4OTE4MWYxMzI2MmU1YTYxZTg0MDg4NDBlMjU3NzgzMDc2N2VkMzY0YmM0ZWUzMWFkNjRjOGJlMjEyODM0JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZnaWYifQ.KvJ0vjAzK1cQJej7Mt1xl0eVRsGPQ-khzjW-ojkORn8"&gt;&lt;img width="640" alt="ATLOCK screenshot" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F233440467%2F644436842-0c3e061f-b19f-4a43-856c-9618e4c8b83b.gif%3Fjwt%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3OTE1NDUyODAsIm5iZiI6MTc5MTU0NDk4MCwicGF0aCI6Ii8yMzM0NDA0NjcvNjQ0NDM2ODQyLTBjM2UwNjFmLWIxOWYtNGE0My04NTZjLTk2MThlNGM4YjgzYi5naWY_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYxMDA5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MTAwOVQxMTIzMDBaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00YTQ4OTE4MWYxMzI2MmU1YTYxZTg0MDg4NDBlMjU3NzgzMDc2N2VkMzY0YmM0ZWUzMWFkNjRjOGJlMjEyODM0JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZnaWYifQ.KvJ0vjAzK1cQJej7Mt1xl0eVRsGPQ-khzjW-ojkORn8"&gt;&lt;/a&gt;
&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🧭 What is ATLOCK?&lt;/h2&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"We build what others forgot to fix."&lt;/em&gt; — Akhouri Systems&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ATLOCK is a &lt;strong&gt;Total Security Suite for Windows&lt;/strong&gt; — built by one developer who got tired of half-baked "lock apps" that promise security and deliver a password prompt.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 Single portable &lt;code&gt;.exe&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🚫 No installation, no setup wizard&lt;/li&gt;
&lt;li&gt;
▶️ Download → Run → Done&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📋 Table of Contents&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#%EF%B8%8F-windows-defender-warning--this-is-a-false-positive" rel="noopener noreferrer"&gt;Windows Defender Warning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#%EF%B8%8F-security-hardening" rel="noopener noreferrer"&gt;Security Hardening&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-architecture" rel="noopener noreferrer"&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-installation" rel="noopener noreferrer"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-whats-new-in-v40" rel="noopener noreferrer"&gt;What's New in v4.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-faq" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-roadmap" rel="noopener noreferrer"&gt;Roadmap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#%EF%B8%8F-disclaimer" rel="noopener noreferrer"&gt;Disclaimer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#-license" rel="noopener noreferrer"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK#%EF%B8%8F-about" rel="noopener noreferrer"&gt;About&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;
⚠️ Windows Defender Warning — This Is a False Positive&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Windows may flag ATLOCK as an &lt;em&gt;"unrecognized app"&lt;/em&gt; or &lt;em&gt;suspicious&lt;/em&gt;. This is a well-known false positive for unsigned, PyInstaller-built Python applications — &lt;strong&gt;it is not malware.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;br&gt;
&lt;b&gt;🛠️ How to run it anyway&lt;/b&gt;…&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;ul&gt;
&lt;li&gt;⬇️ &lt;strong&gt;Direct download (v4):&lt;/strong&gt; &lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;https://fn6qtj.s.gy/ATLOCK-v4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK" rel="noopener noreferrer"&gt;https://github.com/Akhouri-Anmol-Kumar/ATLOCK&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;Akhouri Systems:&lt;/strong&gt; &lt;a href="https://akhouri-anmol-kumar.github.io/Akhouri-systems/" rel="noopener noreferrer"&gt;https://akhouri-anmol-kumar.github.io/Akhouri-systems/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;v4 is the warm-up. v5 is the real thing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Now it's your turn 👇
&lt;/h2&gt;

&lt;p&gt;I genuinely want to hear this, so pick any (or all) of these and fight me in the comments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;When did age help or hurt you&lt;/strong&gt; in tech: a job, a project, a conversation?&lt;/li&gt;
&lt;li&gt;If you saw this exact project from an anonymous account, would you have reacted differently? Be honest. 😅&lt;/li&gt;
&lt;li&gt;Is there an age where "too young" or "too old" is &lt;em&gt;actually true&lt;/em&gt;? Where's the line?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security people:&lt;/strong&gt; what's the first thing you'd attack in a Python encryption suite?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'll be in the comments replying to everyone. Go ahead, tell me I'm wrong. 😄&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by a 13-year-old who still has homework due tomorrow(Lol half-yearly examinations are happening in my school). If you read this far, thank you, and see you on 12 October.&lt;/em&gt; 🔐&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>devdiscuss</category>
      <category>python</category>
      <category>security</category>
    </item>
    <item>
      <title>1,000 downloads. I'm 13. I made you a promise. 🔓</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Thu, 08 Oct 2026 04:16:40 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/1000-downloads-im-13-i-made-you-a-promise-5e7g</link>
      <guid>https://dev.to/akhourianmolkumar/1000-downloads-im-13-i-made-you-a-promise-5e7g</guid>
      <description>&lt;p&gt;A few weeks ago I wrote this on dev.to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"ATLOCK v5 ships when Akhouri Systems crosses 1,000 downloads."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At the time we were at &lt;strong&gt;959&lt;/strong&gt;. Then 967. I kept refreshing like a maniac. 😅&lt;/p&gt;

&lt;p&gt;Today I can say it:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;1,000 downloads. In 5 months. Thank you.&lt;/strong&gt; 🫵
&lt;/h1&gt;

&lt;h2&gt;
  
  
  🙏 First, the thank-you
&lt;/h2&gt;

&lt;p&gt;I'm Anmol, I'm 13, and I build free Windows software alone, on an HP 240 G9, usually at 12 AM.&lt;/p&gt;

&lt;p&gt;Every download is a person who trusted a kid's &lt;code&gt;.exe&lt;/code&gt; on their own PC. Every comment, bug report, and roast made the code better. Here's what you did for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You downloaded &lt;strong&gt;ATLOCK, ANOTE, ACALCU, and APIC&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You told me what was broken. I once posted &lt;em&gt;"I have 511 users and almost zero feedback,"&lt;/em&gt; and you answered.&lt;/li&gt;
&lt;li&gt;You read my code and found problems I'd missed, and I fixed them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nobody handed me an audience. You built it, one download at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔐 So... ATLOCK v5
&lt;/h2&gt;

&lt;p&gt;v4 was the version where I stopped trusting my own encryption and rebuilt it. &lt;strong&gt;v5 is the version where I rebuilt almost everything underneath.&lt;/strong&gt; Here's what's in the development build:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧱 A new crypto core&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AES-256-GCM encryption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Argon2id&lt;/strong&gt; password-based key derivation (memory-hard, so brute-forcing is expensive)&lt;/li&gt;
&lt;li&gt;HKDF domain separation, plus stricter KDF limits so a malicious file can't burn your CPU or RAM&lt;/li&gt;
&lt;li&gt;Optional &lt;strong&gt;TPM-backed&lt;/strong&gt; Windows CNG key support&lt;/li&gt;
&lt;li&gt;A controlled &lt;strong&gt;Vault Recovery Key&lt;/strong&gt; system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🔑 Real second factors&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TOTP and &lt;strong&gt;FIDO2 / YubiKey-class hardware keys&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Panic / decoy vault concept&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🛡️ Security Guard&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows Defender dashboard integration&lt;/li&gt;
&lt;li&gt;VirusTotal hash lookup&lt;/li&gt;
&lt;li&gt;Startup-persistence watchdog&lt;/li&gt;
&lt;li&gt;A ransomware "canary" concept that watches decoy files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🧰 Under the hood&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anti-tamper and rollback protection, plus debugger checks&lt;/li&gt;
&lt;li&gt;Locked and zeroed memory buffers for key material&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic migration&lt;/strong&gt; from older ATLOCK formats, so nothing you protected in v1–v4 gets left behind&lt;/li&gt;
&lt;li&gt;A real CLI (&lt;code&gt;--selftest&lt;/code&gt;, &lt;code&gt;--shred&lt;/code&gt;, &lt;code&gt;--vault-audit&lt;/code&gt;, and more)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quick Lock&lt;/strong&gt;, a Windows Explorer integration so you don't have to open the app to lock a file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this comes from the current development build. Features can still change before release, and I'll tell you honestly what ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  🐛 The part nobody posts about: I audited myself
&lt;/h2&gt;

&lt;p&gt;While building v5 I hunted bugs in my own tool, and &lt;strong&gt;I found six&lt;/strong&gt; that looked fine until they weren't, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an infinite loop in chunked AEAD&lt;/li&gt;
&lt;li&gt;a 2FA lockout&lt;/li&gt;
&lt;li&gt;a file shredder that wrote &lt;strong&gt;one byte&lt;/strong&gt; 😬&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also pasted 8,500 lines into an AI for review. It confidently reported a bug that &lt;strong&gt;didn't exist&lt;/strong&gt;, and &lt;code&gt;grep&lt;/code&gt; proved it. My lesson: &lt;em&gt;demand line numbers, and verify everything.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Security software isn't trustworthy because the author says so. It's trustworthy because people break it and the author fixes it in public. That's why I want &lt;strong&gt;you&lt;/strong&gt; to try to break v5.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 What happens next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Milestone hit: &lt;strong&gt;1,000 downloads&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🔨 v5: final testing and cleanup&lt;/li&gt;
&lt;li&gt;📣 Release: &lt;em&gt;[It is not fixed but high chances are that ATLOCK v5 is set to be released publicly in 12october, 2026]&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;🟢 &lt;strong&gt;ATLOCK v4 is still available and free&lt;/strong&gt; if you want to start now&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Download v4 here: &lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;https://fn6qtj.s.gy/ATLOCK-v4&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🫵 Your mission (yes, you)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Try v4 and tell me what feels slow, confusing, or breakable.&lt;/li&gt;
&lt;li&gt;Open an issue or leave a comment with your roast. I read every one.&lt;/li&gt;
&lt;li&gt;Tell me: &lt;strong&gt;which v5 feature do you want to test first?&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Unsigned apps may get a SmartScreen warning. That's a known false positive for indie PyInstaller builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 Find me
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Website: &lt;a href="https://akhouri-anmol-kumar.github.io/Akhouri-systems/" rel="noopener noreferrer"&gt;https://akhouri-anmol-kumar.github.io/Akhouri-systems/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 GitHub: &lt;a href="https://github.com/Akhouri-Anmol-Kumar" rel="noopener noreferrer"&gt;https://github.com/Akhouri-Anmol-Kumar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 LinkedIn: &lt;a href="https://www.linkedin.com/in/akhourianmolkumar/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/akhourianmolkumar/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1,000 was never the goal. It was the unlock. 🔓&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thank you. v5 is next.&lt;/strong&gt; ⚡&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— Anmol, Akhouri Systems&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>security</category>
      <category>python</category>
      <category>devdiscuss</category>
    </item>
    <item>
      <title>Your GitHub README Isn't a Profile. It's a Storefront. (Here Are the 5 Rules I Used</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Tue, 06 Oct 2026 10:25:07 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/your-github-readme-isnt-a-profile-its-a-storefront-here-are-the-5-rules-i-used-57jm</link>
      <guid>https://dev.to/akhourianmolkumar/your-github-readme-isnt-a-profile-its-a-storefront-here-are-the-5-rules-i-used-57jm</guid>
      <description>&lt;p&gt;Description: "I stopped decorating my GitHub profile and started shipping it like a product page. Four apps, four download buttons, zero widgets."&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%2Flf04rewq51cxy83ni2l6.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%2Flf04rewq51cxy83ni2l6.png" alt=" " width="728" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I [stopped / spent a weekend] treating my GitHub profile like a résumé and started treating it like a &lt;strong&gt;product page&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now a stranger lands on it and can download one of my four apps &lt;strong&gt;before they finish reading my name.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://github.com/Akhouri-Anmol-Kumar" rel="noopener noreferrer"&gt;github.com/Akhouri-Anmol-Kumar&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%2F23a4khtpyoa8hmmk0nxz.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%2F23a4khtpyoa8hmmk0nxz.png" alt=" " width="715" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Credit: the spark to push my profile past badges came from &lt;a href="https://dev.to/georgekobaidze/i-turned-my-github-profile-into-a-cyberpunk-console-with-a-city-built-from-my-contributions-h4c"&gt;Giorgi Kobaidze's cyberpunk-console post&lt;/a&gt;. Go read it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The problem with every "awesome" profile
&lt;/h2&gt;

&lt;p&gt;Open ten popular profile READMEs. You'll see the same things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a wall of badges&lt;/li&gt;
&lt;li&gt;a stats card that shows commit counts&lt;/li&gt;
&lt;li&gt;a "Hi 👋 I'm ___" line&lt;/li&gt;
&lt;li&gt;a snake eating your contribution graph&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They're decorations. None of them answer the question every visitor has in the first three seconds:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;"What can I get from this person, right now?"&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;I build desktop apps: &lt;strong&gt;ATLOCK, APIC, ANOTE and ACALCU&lt;/strong&gt;. So I asked myself a different question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if my README worked like an app store listing?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The 5 Rules of a Storefront README
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rule 1: The 3-Second Download Test
&lt;/h3&gt;

&lt;p&gt;If someone can't download your best work within 3 seconds of landing, the page has failed.&lt;/p&gt;

&lt;p&gt;So each of my apps gets its own card, and &lt;strong&gt;directly under every card is a download button&lt;/strong&gt; that points to the actual &lt;code&gt;.zip&lt;/code&gt; release. There's no "see releases" and no hunting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;align=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://github.com/USER/APP"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"assets/app_card.svg"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"408"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"APP"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://github.com/USER/APP/releases/download/TAG/APP.zip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://img.shields.io/badge/⬇%20DOWNLOAD%20APP-B8935F?style=for-the-badge&amp;amp;labelColor=8a6c3f&amp;amp;logo=windows&amp;amp;logoColor=white"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"38"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Card on top, action underneath. It's the same pattern as a store listing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 2: Pick one metal and never leave it
&lt;/h3&gt;

&lt;p&gt;Mine is &lt;strong&gt;gold&lt;/strong&gt;: &lt;code&gt;#B8935F&lt;/code&gt; for the light tone and &lt;code&gt;#8a6c3f&lt;/code&gt; for the shadow.&lt;/p&gt;

&lt;p&gt;The ring-light logo, the section headers, the buttons and the card edges all use it. Because every element shares one palette, the page looks designed rather than assembled.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Badges look cheap because they're every color at once.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 3: One width, everywhere
&lt;/h3&gt;

&lt;p&gt;Every full-width image on my profile is &lt;strong&gt;830px&lt;/strong&gt;. That's the entire layout system.&lt;/p&gt;

&lt;p&gt;Nothing is slightly wider or narrower than its neighbour, so the page reads as one column instead of a pile of widgets. The app cards are 408px, which is two cards plus a gutter inside that same 830.&lt;/p&gt;

&lt;p&gt;If you only copy one rule from this post, copy this one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 4: Name your sections like paths
&lt;/h3&gt;

&lt;p&gt;My headers aren't "About Me" and "Projects". They are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/links
~/apps
~/status
~/stack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It costs nothing, and it tells a developer in half a second that the person behind the page lives in a terminal. It also makes the page scannable, because every header looks the same and sits in the same place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 5: Make your manifesto a design element, not a paragraph
&lt;/h3&gt;

&lt;p&gt;Right in the middle of the page I put one banner:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Zero telemetry. Zero cloud. Zero subscriptions. Zero ads.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It isn't a bio line. It's the whole product philosophy, rendered as a full-width image. And the page closes with one sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Your machine. Your data. Your control.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Visitors don't remember bullet lists. They remember a line they could repeat.&lt;/p&gt;




&lt;h2&gt;
  
  
  The "no widgets" decision
&lt;/h2&gt;

&lt;p&gt;I made one hard choice: &lt;strong&gt;every visual on my page lives in my own repo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No stat cards from someone else's server. No streak counters that go blank when a free service sleeps. No images that vanish when a third party changes a URL.&lt;/p&gt;

&lt;p&gt;My cards, headers, hero and footer are all SVGs in &lt;code&gt;/assets&lt;/code&gt;, and the only outside piece is the download badge. (If I ever need to remove even that, I can swap in my own SVG.)&lt;/p&gt;

&lt;p&gt;Two details that matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;I use absolute &lt;code&gt;raw.githubusercontent.com&lt;/code&gt; URLs for images&lt;/strong&gt;, so the README still renders if it's copied, mirrored or previewed somewhere else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Everything has alt text&lt;/strong&gt;, including the manifesto banner, so the page works for screen readers and for people whose images fail to load.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The structure at a glance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ ring-light logo ]
[ hero: whoami ]
[ ~/links  → Website · Blog · LinkedIn · Peerlist · Instagram ]
[ ~/apps   → 2×2 grid of cards, each with a DOWNLOAD button ]
[ ~/status → ZERO telemetry banner ]
[ ~/stack  → tech stack ]
[ footer   → "Your machine. Your data. Your control." ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only six sections and one action per app. Nothing on the page is there just to fill space.&lt;/p&gt;




&lt;p&gt;Here's the challenge. &lt;strong&gt;Your profile has one job. Find it, then make that job a button.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selling apps? Put a download button under each one.&lt;/li&gt;
&lt;li&gt;A writer? Put your three best posts as cards.&lt;/li&gt;
&lt;li&gt;A library author? Put &lt;code&gt;npm i your-lib&lt;/code&gt; as the hero.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then &lt;strong&gt;drop your link in the comments&lt;/strong&gt; and tell me the one action your page is built around. I'll read every one.&lt;/p&gt;

&lt;p&gt;Stop decorating your profile and start shipping it. 🚀&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Anmol, and I build privacy-first desktop software at Akhouri Systems.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;🌐 &lt;a href="https://akhouri-anmol-kumar.github.io/Akhouri-systems" rel="noopener noreferrer"&gt;Website&lt;/a&gt; · 💼 &lt;a href="https://www.linkedin.com/in/akhourianmolkumar/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · 🔒 &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK" rel="noopener noreferrer"&gt;ATLOCK&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>design</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>💀 I Hunted Down the Silent Killers in ATLOCK v5 (And Why Your Python App is Probably Failing in Silence) 🔥</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Mon, 05 Oct 2026 08:52:21 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/i-hunted-down-the-silent-killers-in-atlock-v5-and-why-your-python-app-is-probably-failing-in-4jg4</link>
      <guid>https://dev.to/akhourianmolkumar/i-hunted-down-the-silent-killers-in-atlock-v5-and-why-your-python-app-is-probably-failing-in-4jg4</guid>
      <description>&lt;h1&gt;
  
  
  💀 I Hunted Down the Silent Killers in ATLOCK v5 (And Why Your Python App is Probably Failing in Silence) 🔥
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The devil isn't in the missing comma. The devil is in the background thread that silently fails to lock the vault when Windows goes to sleep."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are at &lt;strong&gt;984 downloads&lt;/strong&gt; across all Akhouri Systems products. Just &lt;strong&gt;16 more&lt;/strong&gt; until we hit the 1,000 milestone. &lt;/p&gt;

&lt;p&gt;ATLOCK v5 is &lt;strong&gt;100% built, battle-tested, and ready to ship&lt;/strong&gt;. But before we drop the hammer and release it to the wild, I need to talk about the &lt;em&gt;monsters&lt;/em&gt; I had to slay in the codebase. &lt;/p&gt;

&lt;p&gt;This isn’t a post about "I fixed a missing comma" or "I updated a dependency." This is a deep dive into the &lt;strong&gt;architecture-shattering, silent-failure bugs&lt;/strong&gt; that keep security developers awake at night. &lt;/p&gt;

&lt;p&gt;If you build security tools in Python, &lt;strong&gt;you need to read this.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧵 1. The Tkinter Thread-Safety Illusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Nightmare:&lt;/strong&gt; Background workers (Vault health checks, Defender status updates, Watchdog scans) were directly calling &lt;code&gt;self.after(0, lambda: ...)&lt;/code&gt; to update the UI. &lt;br&gt;
&lt;strong&gt;The Reality:&lt;/strong&gt; Tkinter is &lt;strong&gt;not thread-safe&lt;/strong&gt;. Calling it from a worker thread doesn't always crash immediately. Sometimes, it just silently deadlocks, corrupts the event loop, or vanishes without a trace in the logs. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; I completely ripped out direct UI calls from workers. I built a custom, thread-safe event pump using &lt;code&gt;queue.SimpleQueue&lt;/code&gt; (&lt;code&gt;atl_ui_post&lt;/code&gt; / &lt;code&gt;atl_ui_pump_start&lt;/code&gt;). &lt;br&gt;
Now, background threads &lt;em&gt;only&lt;/em&gt; drop payload functions into the queue. The main Tkinter thread polls this queue and executes the updates safely. &lt;br&gt;
&lt;em&gt;Workers never touch the UI. Period.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🛡️⏱️ 2. The "Frozen Main Thread" Vault Breach
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Nightmare:&lt;/strong&gt; When a user locks their Windows PC (&lt;code&gt;Win + L&lt;/code&gt;), ATLOCK is supposed to instantly lock the Vault and wipe the clipboard. But what if the main UI thread is busy rendering, blocked by an AV scanner, or frozen? The lock command gets queued... and your secrets stay exposed in RAM. &lt;br&gt;
&lt;strong&gt;The Reality:&lt;/strong&gt; Relying solely on the main thread for security-critical state changes is a single point of failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; A &lt;strong&gt;3-second fail-safe timer mechanism&lt;/strong&gt;. &lt;br&gt;
When a session lock is detected, a background thread starts a 3-second countdown. If the main Tk thread fails to pick up the lock command in time, the background daemon &lt;em&gt;forces&lt;/em&gt; the vault lock and nukes the clipboard anyway. &lt;br&gt;
&lt;em&gt;No exceptions. No silent failures. If the UI is frozen, the vault still locks.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📁🚫 3. The &lt;code&gt;Program Files&lt;/code&gt; Permission Trap
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Nightmare:&lt;/strong&gt; The app blindly assumed it could write its encrypted state to &lt;code&gt;&amp;lt;script_folder&amp;gt;/.atlock_data&lt;/code&gt;. &lt;br&gt;
&lt;strong&gt;The Reality:&lt;/strong&gt; If a user places the app in a read-only directory like &lt;code&gt;C:\Program Files&lt;/code&gt; or runs it from a restricted network drive, it throws a &lt;code&gt;PermissionError&lt;/code&gt; on startup and bricks itself. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Introduced &lt;code&gt;_atl_pick_data_dir()&lt;/code&gt;. &lt;br&gt;
It actively probes the script folder for writability. If it passes, it runs in &lt;strong&gt;Portable Mode&lt;/strong&gt;. If it fails, it gracefully falls back to storing data in the per-user &lt;code&gt;%LOCALAPPDATA%\ATLOCK&lt;/code&gt; directory. The app now works flawlessly, regardless of where the user installs it.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌐 4. Secure, Dependency-Free Networking
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Nightmare:&lt;/strong&gt; Relying on the third-party &lt;code&gt;requests&lt;/code&gt; library for Telegram alerts, with a fallback to a basic &lt;code&gt;urllib&lt;/code&gt; implementation that didn't strictly enforce HTTPS and silently swallowed HTTP errors.&lt;br&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; Completely removed the &lt;code&gt;requests&lt;/code&gt; dependency. I wrote a custom, highly secure &lt;code&gt;urllib&lt;/code&gt; implementation (&lt;code&gt;_atl_http_post&lt;/code&gt;) that &lt;strong&gt;strictly enforces HTTPS&lt;/strong&gt;, properly formats multipart form-data for image/video uploads, and &lt;em&gt;raises explicit errors&lt;/em&gt; if the Telegram API rejects the token. No more silent alert failures.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 5. Exception Handling That Doesn't Lie
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Nightmare:&lt;/strong&gt; Heavy reliance on bare &lt;code&gt;except Exception: pass&lt;/code&gt; blocks, which hide critical failures and make debugging impossible.&lt;br&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; Introduced the &lt;code&gt;_atl_swallow()&lt;/code&gt; helper. It safely catches background exceptions and logs &lt;em&gt;only the exception type&lt;/em&gt; to &lt;code&gt;atlock.log&lt;/code&gt; (never the text, which could leak paths or secrets), allowing the app to continue running smoothly while leaving a forensic trail.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚔️ Let's Argue in the Comments (I Dare You)
&lt;/h2&gt;

&lt;p&gt;I want to hear from you. Let’s spark a real discussion:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;How do &lt;em&gt;you&lt;/em&gt; handle background-to-UI communication in single-file Python apps?&lt;/strong&gt; Are you risking &lt;code&gt;tkinter&lt;/code&gt; deadlocks, or do you have a bulletproof queue system?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is a 3-second fail-safe timer overkill, or is it the &lt;em&gt;only&lt;/em&gt; acceptable standard for a security tool?&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What’s the most terrifying "silent failure" bug you’ve ever hunted down in production?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Drop your war stories below. Let’s geek out over thread safety and fail-safes. 👇&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 The Final Countdown: 984 / 1000
&lt;/h2&gt;

&lt;p&gt;ATLOCK v5 is a masterpiece of cryptographic engineering, thread-safe architecture, and fail-closed security. It is 100% built and ready to ship. &lt;/p&gt;

&lt;p&gt;But as a community-driven project, we are waiting to cross the &lt;strong&gt;1,000 total downloads&lt;/strong&gt; milestone across all Akhouri Systems products (we are currently at &lt;strong&gt;984&lt;/strong&gt;). &lt;/p&gt;

&lt;p&gt;Want to see what started it all? Want to test the waters before v5 drops?&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Grab the current stable version (v4) right here:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;https://fn6qtj.s.gy/ATLOCK-v4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Star the repo, track the progress, and be the first to know when v5 drops:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK" rel="noopener noreferrer"&gt;https://github.com/Akhouri-Anmol-Kumar/ATLOCK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Help us cross that 1,000 download mark. Share this post, star the repo, and let’s make ATLOCK the gold standard for local Python security suites. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See you in the comments.&lt;/strong&gt; 💬🔥&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with obsession by Akhouri Anmol Kumar @ Akhouri Systems.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>debugging</category>
      <category>python</category>
      <category>security</category>
      <category>programming</category>
    </item>
    <item>
      <title>We Built a Phone Upgrade Cycle Into a Security App (S25 S26, We See You</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Sun, 04 Oct 2026 13:01:08 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/we-built-a-phone-upgrade-cycle-into-a-security-app-s25-s26-we-see-you-3fph</link>
      <guid>https://dev.to/akhourianmolkumar/we-built-a-phone-upgrade-cycle-into-a-security-app-s25-s26-we-see-you-3fph</guid>
      <description>&lt;h1&gt;
  
  
  We Built a Phone Upgrade Cycle Into a Security App (S25 → S26, We See You)
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Akhouri Systems · ATLOCK Security Suite&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's talk about "upgrades" for a second.&lt;/p&gt;

&lt;p&gt;Samsung drops the S25 Ultra, waits twelve months, slaps in a Snapdragon with a &lt;code&gt;+&lt;/code&gt; next to it, adds a "privacy display" that just... dims when someone looks over your shoulder, and calls it the S26 Ultra. Ships it. Charges you full flagship price again.(in fact 15% more price than the launching price of s25 ultra)&lt;/p&gt;

&lt;p&gt;And then there's the other guy. A fruit company. Forgot the bite mark was supposed to represent &lt;em&gt;progress&lt;/em&gt; somewhere around 2015 and has been shipping the same titanium rectangle with marginally better glass ever since. The bite mark is doing more creative heavy lifting than the actual hardware roadmap at this point.&lt;/p&gt;

&lt;p&gt;Meanwhile we've been sitting here at Akhouri Systems rebuilding our &lt;strong&gt;entire cryptographic core from scratch&lt;/strong&gt; for a free desktop security suite, and nobody's even clapping yet. So let's fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ATLOCK Is
&lt;/h2&gt;

&lt;p&gt;ATLOCK is a single-file, Windows-first, pure-Python security suite — screen lockdown, NTFS-ACL file guarding, an encrypted credential vault, and intruder-capture (photo + video) wired into one app(.exe). No subscription. No cloud. No telemetry phoning home to some VC's dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v4&lt;/strong&gt; is live right now: 👉 &lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;Download ATLOCK v4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v5&lt;/strong&gt; is done. Fully built. Sitting in the chamber. And it is not a "Gen+ chip and a privacy display" update — it's a ground-up rebuild of everything that actually matters in a security tool: the crypto, the storage format, and the attack surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Part (because talk is cheap)
&lt;/h2&gt;

&lt;p&gt;Here's the actual diff, not marketing copy:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;v4&lt;/th&gt;
&lt;th&gt;v5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vault encryption&lt;/td&gt;
&lt;td&gt;Fernet (AES-128-CBC + HMAC)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;AES-256-GCM&lt;/strong&gt;, authenticated, chunked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key derivation&lt;/td&gt;
&lt;td&gt;PBKDF2-HMAC-SHA256, 200k iters&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;HKDF&lt;/strong&gt; + hardened key sealing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File containers&lt;/td&gt;
&lt;td&gt;basic encrypted blob&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Container format v3.1&lt;/strong&gt; — chunked AES-256-GCM, key commitment, per-chunk subkeys, optional Padme size padding, header-bound AAD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2FA&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;TOTP + FIDO2 hardware key support&lt;/strong&gt; (YubiKey, WebAuthn)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recovery&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Shamir secret sharing&lt;/strong&gt; (&lt;code&gt;--shamir-split&lt;/code&gt; / &lt;code&gt;--shamir-join&lt;/code&gt;) — split your recovery key across multiple people/locations, no single point of failure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public-key crypto&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Full &lt;code&gt;--pk-keygen / --pk-encrypt / --sign / --check-sig&lt;/code&gt; pipeline, plus &lt;strong&gt;signed-release verification&lt;/strong&gt; so you can confirm a build actually came from us&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anti-rollback&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;HardenedState sealed anchors resist clock/state rollback attacks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-defense&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--selftest&lt;/code&gt;, &lt;code&gt;--canary-selftest&lt;/code&gt;, &lt;code&gt;--fuzz&lt;/code&gt; (stress-tests the container parser against random corruption), &lt;code&gt;--audit-verify&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Known v4 weak spot&lt;/td&gt;
&lt;td&gt;a documented stealth recovery bypass, flagged openly in the v4 source as a ship-at-your-own-risk tradeoff&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;gone&lt;/strong&gt; — rebuilt around FIDO2 + Shamir recovery instead of a hidden master sequence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legacy data&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;v1-v3 containers and v4/v5 JSON vault/guard/settings files are auto-migrated, nothing left behind&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is what a real upgrade cycle looks like. Not "the same silicon, now 8% faster." A rewritten trust model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pitch
&lt;/h2&gt;

&lt;p&gt;v5 is &lt;strong&gt;100% built, tested, and ready to ship.&lt;/strong&gt; It is not gated behind more dev time, more testing, more "coming soon" vaporware energy. It's gated behind exactly one number:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Akhouri Systems is at 975 / 1000 total downloads across all products.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;v5 unlocks at 1,000.&lt;/p&gt;

&lt;p&gt;That's it. That's the whole gate. 25 downloads stand between you and a security suite that out-engineers products made by companies worth more than some countries' GDP.&lt;/p&gt;

&lt;p&gt;So here's the move: go grab &lt;strong&gt;v4&lt;/strong&gt; right now — it's free, it's real, it works — and you personally become one of the 25 people who flip the switch on v5 for everyone.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;Download ATLOCK v4 here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Discuss
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What's the most embarrassing "flagship upgrade" you've ever paid for?&lt;/li&gt;
&lt;li&gt;FIDO2 vs TOTP vs Shamir recovery — which would you actually trust for a personal vault?&lt;/li&gt;
&lt;li&gt;Anyone want to pressure-test the v5 container format once it's out? &lt;code&gt;--fuzz&lt;/code&gt; is going to need friends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a comment, drop a download, let's hit four digits. 🔐&lt;/p&gt;

&lt;p&gt;— &lt;em&gt;Akhouri Anmol Kumar, Akhouri Systems&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>security</category>
      <category>cybersecurity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Let an AI Audit My Password Vault. It Lied to Me With Total Confidence. 🔐</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Sun, 04 Oct 2026 04:49:35 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/i-let-an-ai-audit-my-password-vault-it-lied-to-me-with-total-confidence-2b22</link>
      <guid>https://dev.to/akhourianmolkumar/i-let-an-ai-audit-my-password-vault-it-lied-to-me-with-total-confidence-2b22</guid>
      <description>&lt;h1&gt;
  
  
  🚨 "Brother, I read the whole code carefully. These bugs are real."
&lt;/h1&gt;

&lt;p&gt;That's how it started.&lt;/p&gt;

&lt;p&gt;I'd been building &lt;strong&gt;ATLOCK&lt;/strong&gt;, a Windows security suite with an encrypted password vault, file guard, 2FA, the works. v5 was nearly done. So I did what every developer does at some point: I pasted 8,500 lines of Python into an AI and asked,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Any bugs?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It came back with &lt;strong&gt;six&lt;/strong&gt;. Emojis, severity colors, function names, even a smug little &lt;em&gt;"I didn't invent these, you can verify them yourself."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Reader, I took that offer literally. 😏&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 The Rules of the Game
&lt;/h2&gt;

&lt;p&gt;For every claim I did one thing: &lt;strong&gt;open the actual file and check.&lt;/strong&gt;&lt;br&gt;
No vibes. No trust. Just &lt;code&gt;grep&lt;/code&gt; and line numbers.&lt;/p&gt;

&lt;p&gt;Final score:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Claim&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Vault recovery key crashes&lt;/td&gt;
&lt;td&gt;🔴 &lt;strong&gt;Real&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Watchdog silently skips services&lt;/td&gt;
&lt;td&gt;🤥 &lt;strong&gt;Fiction&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Enabling 2FA locks you out&lt;/td&gt;
&lt;td&gt;🟠 &lt;strong&gt;Real&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;HIBP request on every keystroke&lt;/td&gt;
&lt;td&gt;🟡 &lt;strong&gt;Real&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Wrong key derivation for v2 vaults&lt;/td&gt;
&lt;td&gt;😇 &lt;strong&gt;Real, but harmless&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Factory reset race condition&lt;/td&gt;
&lt;td&gt;🟡 &lt;strong&gt;Real&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Four real bugs, one fake, one harmless. Let's go through them. 🍿&lt;/p&gt;


&lt;h2&gt;
  
  
  💥 Bug #1: The Feature That Could Never Have Worked
&lt;/h2&gt;

&lt;p&gt;Creating a &lt;strong&gt;Vault Recovery Key&lt;/strong&gt; called 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="n"&gt;enc_b64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_sess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;())).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ascii&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;SecureBuffer&lt;/code&gt; 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;class&lt;/span&gt; &lt;span class="nc"&gt;SecureBuffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="c1"&gt;# view()? Never heard of her.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click &lt;em&gt;"Create Vault Recovery Key"&lt;/em&gt; → &lt;code&gt;AttributeError&lt;/code&gt;. 💀&lt;br&gt;
It's the one feature meant to save you when you forget your password, and it crashed on creation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; one line.&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="n"&gt;enc_b64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_sess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_bytes&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ascii&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Lesson: a recovery feature nobody tests is a recovery feature that doesn't exist.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔒 Bug #3: Enabling 2FA Locked Me Out of My Own Vault
&lt;/h2&gt;

&lt;p&gt;This one is my favorite, because it's &lt;em&gt;sneaky&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When you enable TOTP in Settings, the app creates a &lt;strong&gt;fresh&lt;/strong&gt; &lt;code&gt;PasswordVault()&lt;/code&gt;, writes the 2FA config to disk, and shows you a lovely QR code. Everything looks perfect.&lt;/p&gt;

&lt;p&gt;But the main app is holding a &lt;strong&gt;different&lt;/strong&gt; vault object, loaded once at startup, with a memory that has no idea 2FA now exists.&lt;/p&gt;

&lt;p&gt;So you lock the vault, try to unlock it, and your own app says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"TOTP is required by your security policy but not set up. Access denied."&lt;/em&gt; 🙃&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes. The policy says &lt;em&gt;"2FA required"&lt;/em&gt;, the stale in-memory copy says &lt;em&gt;"2FA doesn't exist"&lt;/em&gt;, and the vault, being a good fail-closed security tool, slams the door on you.&lt;/p&gt;

&lt;p&gt;Funny part: it's the &lt;em&gt;safe&lt;/em&gt; kind of bug. Annoying, but it never leaked anything. A password manager that locks you out beats one that lets everyone in. 😅&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; re-read the 2FA config from disk right before checking the second factor.&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;def&lt;/span&gt; &lt;span class="nf"&gt;_sync_mfa_from_disk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;contextlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;suppress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;disk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atlock_read_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mfa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mfa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mfa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mfa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# in unlock(), right before the 2FA check:
&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_sync_mfa_from_disk&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ok2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atl_second_factor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Vault unlock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ask_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ask_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bonus: this also covers someone enabling 2FA from the CLI while the app is open.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌐 Bug #4: Typing a Password Sent a Small Army of Network Requests
&lt;/h2&gt;

&lt;p&gt;When you add a vault entry, ATLOCK checks your password against Have I Been Pwned. Great feature. Terrible implementation:&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_pw_e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;KeyRelease&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_on_password_change&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# every. single. key.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type a 12-character password and the app spawns about &lt;strong&gt;7 threads and 7 API calls&lt;/strong&gt;. Rate limits and UI lag, free of charge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; a classic debounce. Wait until the user &lt;em&gt;stops typing&lt;/em&gt; for 700 ms, then check once.&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_hibp_after&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;700&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_run_hibp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the password changed while the request was in flight, the stale result is thrown away. No more flickering "✓ Safe" labels for passwords you've already deleted.&lt;/p&gt;




&lt;h2&gt;
  
  
  🗑️ Bug #6: Factory Reset vs. The Process That Wouldn't Leave
&lt;/h2&gt;

&lt;p&gt;Factory Reset worked like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Spawn a new process that deletes everything&lt;/li&gt;
&lt;li&gt;Close the current app&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The problem: step 1 happens &lt;em&gt;while the old app still holds its file handles&lt;/em&gt;. On Windows, deleting a file another process still has open gives you &lt;code&gt;PermissionError&lt;/code&gt;, and you get a &lt;strong&gt;half-erased&lt;/strong&gt; reset. Spooky. 👻&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; the reset process now receives the parent's PID and politely waits for it to exit.&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="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Popen&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--reset&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--reset-wait-pid=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getpid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows it waits on the process handle (up to 10 seconds) before wiping anything. Manners matter, even in a destructive operation.&lt;/p&gt;




&lt;h2&gt;
  
  
  😇 Bug #5: Real, But Nobody Is Ever Affected
&lt;/h2&gt;

&lt;p&gt;The claim: Quick Lock always derives the master key with the &lt;em&gt;legacy v1&lt;/em&gt; function, even for v2 vaults.&lt;/p&gt;

&lt;p&gt;True in the code. But I traced who can ever reach it: &lt;strong&gt;TOTP and FIDO2 setup require a v3 vault.&lt;/strong&gt; A legacy v2 vault can never have a second factor, so there's nothing to unwrap with the wrong key.&lt;/p&gt;

&lt;p&gt;So: technically inconsistent, practically unreachable. I left it alone. Knowing &lt;em&gt;what not to fix&lt;/em&gt; is also engineering. 🧘&lt;/p&gt;




&lt;h2&gt;
  
  
  🤥 Bug #2: The One That Never Existed
&lt;/h2&gt;

&lt;p&gt;The most dramatic claim:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Watchdog calls &lt;code&gt;DefenderGuard.run_ps&lt;/code&gt;, but the method is &lt;code&gt;_run_ps&lt;/code&gt;! It silently skips services and scheduled tasks! A big hole in persistence detection!"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It even offered &lt;em&gt;proof&lt;/em&gt;: &lt;em&gt;"the WMI function spells it correctly, so the other two are obviously typos."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I searched the entire file:&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;-n&lt;/span&gt; &lt;span class="s2"&gt;"DefenderGuard&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;run_ps"&lt;/span&gt; ATLOCK_V5.py
&lt;span class="c"&gt;# (nothing)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero results. Every call was already &lt;code&gt;_run_ps&lt;/code&gt;. The bug was &lt;strong&gt;invented&lt;/strong&gt;, complete with a convincing explanation of how it happened and why it matters.&lt;/p&gt;

&lt;p&gt;And the best part? I fed the &lt;em&gt;fixed&lt;/em&gt; file back to the AI, and it confidently re-confirmed all the old bugs, including the fake one, &lt;strong&gt;even the ones I'd already fixed.&lt;/strong&gt; It even reproduced the typo with a stray space (&lt;code&gt;DefenderGuard. run_ps&lt;/code&gt;) that exists nowhere in my code. 🤡&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What I Actually Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. AI code review is a great &lt;em&gt;scout&lt;/em&gt;, and a terrible &lt;em&gt;judge&lt;/em&gt;.&lt;/strong&gt;&lt;br&gt;
It found four real bugs I'd missed. That's genuinely valuable. It also invented one with the same confident voice. You can't tell them apart without checking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Demand line numbers.&lt;/strong&gt;&lt;br&gt;
A real bug can be pointed at. If a claim has no line number, it's a rumor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. &lt;code&gt;grep&lt;/code&gt; is a lie detector.&lt;/strong&gt;&lt;br&gt;
Every claim here took about ten seconds to verify. Ten seconds beats a week of "fixing" a bug that doesn't exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Trace before you fix.&lt;/strong&gt;&lt;br&gt;
Bug #5 was real and still not worth a patch. Reachability matters more than correctness-in-the-abstract.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Fail-closed bugs are the good kind of bad.&lt;/strong&gt;&lt;br&gt;
When your security tool breaks, it should break &lt;em&gt;shut&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛡️ So... What's ATLOCK?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ATLOCK&lt;/strong&gt; is a Windows security suite by &lt;strong&gt;Akhouri Systems&lt;/strong&gt;: an Argon2id-based encrypted password vault, file guard, TOTP and FIDO2 2FA, panic/decoy vault, breach checks, startup watchdog, and more.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;v4 is out now:&lt;/strong&gt; &lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;Download ATLOCK v4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔥 &lt;strong&gt;v5 (everything you just read about) is coming soon&lt;/strong&gt;, and I'm releasing it when Akhouri Systems crosses &lt;strong&gt;1,000 downloads&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;📊 Current progress: &lt;strong&gt;967 / 1000&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's &lt;strong&gt;33 downloads&lt;/strong&gt; away. If you've ever wanted to be the reason a security tool ships its next version, you know what to do. 😄&lt;/p&gt;

&lt;p&gt;⭐ Repo: &lt;a href="https://github.com/Akhouri-Anmol-Kumar/ATLOCK" rel="noopener noreferrer"&gt;github.com/Akhouri-Anmol-Kumar/ATLOCK&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 Your Turn
&lt;/h2&gt;

&lt;p&gt;Has an AI ever confidently "found" a bug that didn't exist in your code? Drop your best hallucination story below. 👇 I'll start a collection.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built by Akhouri Anmol Kumar, one very suspicious &lt;code&gt;grep&lt;/code&gt; at a time.&lt;/em&gt; 🔍&lt;/p&gt;

</description>
      <category>debugging</category>
      <category>security</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>Auditing My Own Encryption Tool: 6 Bugs That Looked Fine Until They Weren't</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Sat, 03 Oct 2026 11:44:29 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/auditing-my-own-encryption-tool-6-bugs-that-looked-fine-until-they-werent-3g2j</link>
      <guid>https://dev.to/akhourianmolkumar/auditing-my-own-encryption-tool-6-bugs-that-looked-fine-until-they-werent-3g2j</guid>
      <description>&lt;h2&gt;
  
  
  Description: "An infinite loop in chunked AEAD, a 2FA lockout, a shredder that wrote one byte, and more. A technical walkthrough of bugs found in ATLOCK v5, a Python file-locking tool."
&lt;/h2&gt;

&lt;p&gt;I build &lt;strong&gt;ATLOCK&lt;/strong&gt;, a Windows file and folder locking tool in Python. It uses&lt;br&gt;
Argon2 key derivation, chunked AES-GCM containers, a password vault with TOTP&lt;br&gt;
2FA, and a "panic password" that opens a decoy vault.&lt;/p&gt;

&lt;p&gt;Before shipping the next version, I audited the whole file (about 8,500&lt;br&gt;
lines). Most of what I expected to find, such as OCR-style corruption, bad&lt;br&gt;
indentation and trailing spaces in strings, turned out not to be present. The&lt;br&gt;
interesting bugs were logic bugs in security-sensitive paths. Here are the&lt;br&gt;
real ones, with the reasoning and the fixes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  📦 Availability
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ATLOCK v5 is not released yet.&lt;/strong&gt; It ships when Akhouri Systems crosses&lt;br&gt;
&lt;strong&gt;1,000 downloads&lt;/strong&gt;, and we're currently at &lt;strong&gt;959&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the meantime you can try &lt;strong&gt;ATLOCK v4&lt;/strong&gt; here:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;https://fn6qtj.s.gy/ATLOCK-v4&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything described below is part of the v5 work. v5 is the upgrade&lt;br&gt;
path once the milestone is hit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  1. The infinite loop in chunked encryption
&lt;/h2&gt;

&lt;p&gt;ATLOCK writes containers as a stream of AES-GCM chunks. The header declares&lt;br&gt;
the plaintext length up front, and each chunk is authenticated with&lt;br&gt;
associated data (AAD) that binds three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the header hash&lt;/li&gt;
&lt;li&gt;the chunk index&lt;/li&gt;
&lt;li&gt;a flag marking whether it is the final chunk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simplified, the encrypt loop looked 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="bp"&gt;True&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;fh_in&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;is_final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;written&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;len&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="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;plain_len&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nonce_base&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;I&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;aad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;header_hash&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;I&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_final&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nonce&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="n"&gt;aad&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ... write, written += len(chunk), idx += 1
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_final&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;is_final&lt;/code&gt; is computed from &lt;code&gt;written&lt;/code&gt;, which only grows when &lt;code&gt;read()&lt;/code&gt;&lt;br&gt;
returns data. If the source file &lt;strong&gt;shrinks while it is being read&lt;/strong&gt;&lt;br&gt;
(another process truncates it, a sync client rewrites it, a user saves),&lt;br&gt;
&lt;code&gt;read()&lt;/code&gt; returns &lt;code&gt;b""&lt;/code&gt;. &lt;code&gt;written&lt;/code&gt; stops increasing and &lt;code&gt;is_final&lt;/code&gt; never&lt;br&gt;
becomes true. The loop spins forever, writing empty encrypted chunks, and the&lt;br&gt;
app freezes.&lt;/p&gt;
&lt;h3&gt;
  
  
  The tempting fix is wrong
&lt;/h3&gt;

&lt;p&gt;The obvious patch is to force termination:&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;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;is_final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ends the loop, but it produces a &lt;strong&gt;silently corrupt vault&lt;/strong&gt;. The header&lt;br&gt;
already promises &lt;code&gt;plain_len&lt;/code&gt; bytes. The reader derives "is this the last&lt;br&gt;
chunk?" from that length, so it will expect the final-flag AAD at a different&lt;br&gt;
point than the one you wrote. Decryption fails authentication, and you find&lt;br&gt;
out only when the user needs the data. A freeze is better than that, because&lt;br&gt;
at least it is visible.&lt;/p&gt;
&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;Fail loudly, and also stop reading past the declared length so a file that&lt;br&gt;
&lt;em&gt;grows&lt;/em&gt; can't be silently truncated:&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="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fh_in&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plain_len&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;written&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;plain_len&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;written&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;plain_len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;AtlockDamaged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Source file changed size during encryption (it became shorter). &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nothing was replaced; please retry.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;is_final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;written&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;len&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="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;plain_len&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I tested four cases: a shrinking source (raises, does not hang), a growing&lt;br&gt;
source (round-trips to exactly the declared length), an empty file, and&lt;br&gt;
normal files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; when the format commits to a length in the header, never let the&lt;br&gt;
loop terminate on anything but that length.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. A 2FA lockout for legacy vaults
&lt;/h2&gt;

&lt;p&gt;Quick Lock re-authenticates the user, then runs the second factor. For&lt;br&gt;
&lt;strong&gt;legacy (pre-v3) vaults&lt;/strong&gt; there is no v3 &lt;code&gt;master&lt;/code&gt; section, so the derived&lt;br&gt;
master key is &lt;code&gt;None&lt;/code&gt;. The call site did 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="nf"&gt;atl_second_factor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quick Lock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The TOTP seed is stored wrapped under the master key. Unwrapping it with an&lt;br&gt;
empty key always fails authentication. Anyone on a legacy vault with a TOTP&lt;br&gt;
policy would fail Quick Lock every time, with no way back in.&lt;/p&gt;

&lt;p&gt;The fix is to derive the real key with the legacy KDF before discarding the&lt;br&gt;
password:&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;if&lt;/span&gt; &lt;span class="n"&gt;legacy_ok&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;contextlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;suppress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;master&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atlock_legacy_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;master_salt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;pwd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One caveat I verified before claiming too much: TOTP can only be configured&lt;br&gt;
on &lt;em&gt;migrated&lt;/em&gt; vaults, so a pure legacy vault has no seed to unwrap. In that&lt;br&gt;
case the existing behaviour (denied, "not set up") is still the correct&lt;br&gt;
fail-closed result. The change makes the code correct instead of relying on&lt;br&gt;
that accident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; &lt;code&gt;x or b""&lt;/code&gt; as a default for key material is a smell. A dummy key&lt;br&gt;
doesn't fail safe. It fails permanently.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. The shredder that wrote one byte
&lt;/h2&gt;

&lt;p&gt;This one is my favourite because two bugs combined.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug A: the return value was ignored.&lt;/strong&gt; After re-encrypting a guarded file,&lt;br&gt;
the code securely deleted the plaintext working copy:&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="nf"&gt;atlock_shred&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# returns False if it couldn't delete
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows, if the user leaves the file open in Word or Notepad, the delete&lt;br&gt;
fails with &lt;code&gt;WinError 32&lt;/code&gt; (sharing violation). &lt;code&gt;atlock_shred&lt;/code&gt; returned &lt;code&gt;False&lt;/code&gt;&lt;br&gt;
correctly, but the caller dropped its "pending re-encrypt" record anyway. The&lt;br&gt;
result was a plaintext file sitting on disk with nothing tracking it.&lt;/p&gt;

&lt;p&gt;The fix is to treat a failed shred as a failed operation, so the retry timer&lt;br&gt;
and the on-startup recovery keep the record:&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;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;atlock_shred&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;PermissionError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;working copy is still open in another program&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also added a "Please close the file" notification on the first failure,&lt;br&gt;
instead of leaving the user to find out from a log line. Retries run every 15&lt;br&gt;
seconds for up to 10 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug B: the zero-fill pass wrote 1 byte.&lt;/strong&gt;&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="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass 0 wrote a single byte per block-sized step, while &lt;code&gt;left&lt;/code&gt; was&lt;br&gt;
decremented by &lt;code&gt;n&lt;/code&gt;. The zero pass barely touched the file. The random pass&lt;br&gt;
was correct. The fix:&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="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An honest caveat: on SSDs with wear levelling, or on copy-on-write and&lt;br&gt;
journaling filesystems, overwriting in place is not a guarantee of&lt;br&gt;
irrecoverability anyway. Shredding is best-effort hygiene, not a&lt;br&gt;
forensic-grade guarantee, and the docs should say so.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. The old panic password survived key rotation
&lt;/h2&gt;

&lt;p&gt;ATLOCK has a panic password that opens a decoy vault. Vaults migrated from the&lt;br&gt;
old format carry that panic slot into the new one. &lt;code&gt;rotate_master&lt;/code&gt; replaced&lt;br&gt;
the real master key but left the panic slot untouched, so after rotating&lt;br&gt;
because "my password leaked", &lt;strong&gt;the old panic password still opened the&lt;br&gt;
decoy forever&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I can't re-derive the panic hash without the panic password, so the right&lt;br&gt;
move is to retire the slot. I replaced it with an inert slot of the same&lt;br&gt;
shape (so the file doesn't reveal that anything changed) and a fresh random&lt;br&gt;
decoy blob, and told the user to set a new panic password:&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;if&lt;/span&gt; &lt;span class="n"&gt;psec0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;legacy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;panic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;salt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sec&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;verifier&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token_hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;real&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;decoy_entries_enc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gcm3:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also made rotation reject a new master password that equals an active panic&lt;br&gt;
password, which would otherwise make both open the same vault.&lt;/p&gt;

&lt;p&gt;A user-chosen panic password on a v3 vault is independent of the master key,&lt;br&gt;
so I left those alone. The bug was specifically the carried-over legacy slot.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Hammering the HIBP API
&lt;/h2&gt;

&lt;p&gt;The vault's health audit checks every password against Have I Been Pwned&lt;br&gt;
using the k-anonymity range API. It did so in a tight loop. With 50 or more&lt;br&gt;
entries, you hit rate limits and the later checks fail quietly.&lt;/p&gt;

&lt;p&gt;Fixes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;time.sleep(0.5)&lt;/code&gt; between &lt;em&gt;real&lt;/em&gt; requests&lt;/li&gt;
&lt;li&gt;a per-audit cache, so identical passwords are looked up once&lt;/li&gt;
&lt;li&gt;stop after the first offline or rate-limited result, instead of waiting for
a timeout on every remaining entry
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hibp_cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hibp_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;hibp_calls&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;hibp_cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atlock_hibp_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hibp_cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;hibp_offline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The audit already ran on a worker thread, so the delay doesn't freeze the UI.&lt;br&gt;
A test with 5 unique passwords plus one duplicate made 5 calls and 4 sleeps,&lt;br&gt;
as expected.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Compiling with Nuitka: &lt;code&gt;sys.frozen&lt;/code&gt; isn't set
&lt;/h2&gt;

&lt;p&gt;This isn't a classic bug, but it would have bitten me in production.&lt;br&gt;
PyInstaller sets &lt;code&gt;sys.frozen&lt;/code&gt;. &lt;strong&gt;Nuitka does not.&lt;/strong&gt; My code decided how to&lt;br&gt;
re-launch itself (background agent, Explorer context menu, factory reset)&lt;br&gt;
with:&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;if&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;frozen&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--background-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a Nuitka build that check is false, so the code takes the "running as a&lt;br&gt;
&lt;code&gt;.py&lt;/code&gt;" path and builds a broken command line. Nuitka injects a module-level&lt;br&gt;
&lt;code&gt;__compiled__&lt;/code&gt; instead:&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="n"&gt;IS_COMPILED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;frozen&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__compiled__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;atl_self_exe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;IS_COMPILED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executable&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.exe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also skipped the &lt;code&gt;importlib.util.find_spec&lt;/code&gt; dependency pre-check in&lt;br&gt;
compiled mode, since everything is already bundled, and pointed the&lt;br&gt;
release-signature hash at the &lt;code&gt;.exe&lt;/code&gt; instead of a &lt;code&gt;.py&lt;/code&gt; that no longer exists.&lt;/p&gt;

&lt;p&gt;I recommend &lt;code&gt;--standalone&lt;/code&gt; over &lt;code&gt;--onefile&lt;/code&gt; for this kind of tool. Onefile&lt;br&gt;
unpacks to a temp directory on every launch, which makes self-integrity&lt;br&gt;
checks and registry or scheduled-task paths less predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I didn't find
&lt;/h2&gt;

&lt;p&gt;An early checklist claimed the file was full of OCR damage: broken dunder&lt;br&gt;
methods, &lt;code&gt;isinstan ce&lt;/code&gt;, &lt;code&gt;1 &amp;lt; &amp;lt; 20&lt;/code&gt;, trailing spaces inside every string, and&lt;br&gt;
mixed indentation. I verified each item mechanically and &lt;strong&gt;none of it was&lt;br&gt;
there&lt;/strong&gt;. I used &lt;code&gt;tokenize&lt;/code&gt; for the string literals and indentation steps, and&lt;br&gt;
&lt;code&gt;pyflakes&lt;/code&gt; plus &lt;code&gt;py_compile&lt;/code&gt; for names and syntax.&lt;/p&gt;

&lt;p&gt;The lesson is to verify a claimed bug list against the actual file before&lt;br&gt;
"fixing" it. The real bugs were subtler and more dangerous than formatting&lt;br&gt;
problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Don't terminate loops on convenience.&lt;/strong&gt; If a format commits to a length,
mismatches should be errors, not quiet terminations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Placeholder key material (&lt;code&gt;or b""&lt;/code&gt;) fails closed forever.&lt;/strong&gt; Derive the
real key, or deny cleanly with a reason.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always check the result of security-relevant cleanup&lt;/strong&gt;, such as
deletes and shreds. A swallowed &lt;code&gt;False&lt;/code&gt; leaves plaintext behind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test the helper's internals, not only its API.&lt;/strong&gt; &lt;code&gt;b"\x00"&lt;/code&gt; vs
&lt;code&gt;b"\x00" * n&lt;/code&gt; passes every "it returned True" test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key rotation must cover every credential derived from the old state&lt;/strong&gt;,
including secondary ones like panic and decoy slots.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Know your compiler's markers.&lt;/strong&gt; Nuitka and PyInstaller differ here.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What I couldn't test on Linux: the Windows-specific parts (the Quick Lock&lt;br&gt;
dialog, real &lt;code&gt;WinError 32&lt;/code&gt; file-lock retries, and the compiled &lt;code&gt;.exe&lt;/code&gt;). I&lt;br&gt;
tested those by reading and by simulating the code paths, so I'm calling them&lt;br&gt;
unverified on real Windows until I've run them there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try ATLOCK
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;v5 is coming&lt;/strong&gt; once Akhouri Systems reaches 1,000 downloads (we're at 959,&lt;br&gt;
so very close). Until then, grab &lt;strong&gt;ATLOCK v4&lt;/strong&gt; and upgrade when v5 lands:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;https://fn6qtj.s.gy/ATLOCK-v4&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you find a bug in the tool, I'd like to hear about it, and I'll write it up&lt;br&gt;
the same way.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>python</category>
      <category>coding</category>
      <category>testing</category>
    </item>
    <item>
      <title>A stranger publicly roasted my encryption tool. He was right. Here's the bug that said "SAFE ✅" while offline.</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Fri, 02 Oct 2026 08:15:38 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/a-stranger-publicly-roasted-my-encryption-tool-he-was-right-heres-the-bug-that-said-safe--1n9c</link>
      <guid>https://dev.to/akhourianmolkumar/a-stranger-publicly-roasted-my-encryption-tool-he-was-right-heres-the-bug-that-said-safe--1n9c</guid>
      <description>&lt;p&gt;Description: I let a reviewer pick apart my encryption tool. He found a bug that told users "safe" when it meant "unknown". Here's every fix, the attacks I ran on my own files, and how to get v5 early.&lt;/p&gt;




&lt;p&gt;Last I posted about &lt;strong&gt;ATLOCK v5&lt;/strong&gt;, my encryption and password-vault tool. Within hours, a reviewer left a comment longer than most of my commits.&lt;/p&gt;

&lt;p&gt;It was polite. It was precise. It was devastating.&lt;/p&gt;

&lt;p&gt;I could have gotten defensive. Instead I opened the code and tried to prove him wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some of it, he was.&lt;/strong&gt; Here's what I found.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐛 Bug #1: the "SAFE ✅" that meant "I have no idea"
&lt;/h2&gt;

&lt;p&gt;ATLOCK checks your passwords against known breaches using the Have I Been Pwned range API. Only a 5-character hash prefix ever leaves your machine. Your password never does.&lt;/p&gt;

&lt;p&gt;The flaw: if the check &lt;em&gt;couldn't run&lt;/em&gt; (offline, blocked, timed out), the code quietly returned "not breached", and the UI showed a calm green &lt;strong&gt;"Safe from breaches."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A security tool saying &lt;em&gt;safe&lt;/em&gt; when it means &lt;em&gt;unknown&lt;/em&gt; is the worst kind of bug, because it looks like it's working.&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="c1"&gt;# before: couldn't check -&amp;gt; "not breached"
&lt;/span&gt;&lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="nf"&gt;else &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# after: unknown stays unknown
&lt;/span&gt;&lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="nf"&gt;else &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it says &lt;strong&gt;"Could not check, NOT verified."&lt;/strong&gt; The vault health audit has its own "could not be checked" section. Silence is no longer a green tick.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚪 Bug #2: three network calls that trusted too much
&lt;/h2&gt;

&lt;p&gt;Three &lt;code&gt;urlopen&lt;/code&gt; calls accepted whatever URL scheme came along and followed redirects wherever a server pointed them. Now every request goes through one helper that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;refuses anything that isn't &lt;code&gt;https&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;refuses a redirect to anything that isn't &lt;code&gt;https&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;always applies a timeout and a response size cap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One door. One lock.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔨 "Your 200 bit-flip test mostly tests GCM's tag"
&lt;/h2&gt;

&lt;p&gt;Ouch. And fair.&lt;/p&gt;

&lt;p&gt;Flipping random bits proves AES-GCM's tag works. It doesn't prove my &lt;em&gt;chunk logic&lt;/em&gt; works, and that's exactly where chunked encryption breaks: reordering, duplication, truncation.&lt;/p&gt;

&lt;p&gt;So I wrote the attacks he described and aimed them at my own encrypted files:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack on an encrypted file&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Flip one bit in &lt;strong&gt;every single header byte&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;❌ rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swap two chunks&lt;/td&gt;
&lt;td&gt;❌ rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Duplicate one chunk over another&lt;/td&gt;
&lt;td&gt;❌ rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drop the first chunk&lt;/td&gt;
&lt;td&gt;❌ rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Append an extra chunk&lt;/td&gt;
&lt;td&gt;❌ rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Truncate &lt;strong&gt;exactly on a chunk boundary&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;❌ rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cut the file at an earlier "valid-looking" point&lt;/td&gt;
&lt;td&gt;❌ never opens as a whole file&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every chunk authenticates its own index and a final-chunk flag, so a truncated file can never pass for a complete one.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔑 Sender pinning: fail closed, not "please read the warning"
&lt;/h2&gt;

&lt;p&gt;If you pin a sender's public key and the file is unsigned or signed by someone else, ATLOCK &lt;strong&gt;refuses&lt;/strong&gt;. It raises an exception &lt;em&gt;before any plaintext is written&lt;/em&gt;. Reading it anyway takes an explicit &lt;code&gt;allow_sender_mismatch=True&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why not just warn? Because a warning only works if a human reads it. A return value like &lt;code&gt;{'signed': True, 'signer_matches': False}&lt;/code&gt; is exactly what a script checks halfway and ignores. The new test confirms that on a mismatch, &lt;strong&gt;nothing is left on disk.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧾 What I am NOT claiming
&lt;/h2&gt;

&lt;p&gt;I'd rather you hear it from me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No third-party audit.&lt;/strong&gt; The crypto primitives come from &lt;code&gt;cryptography&lt;/code&gt; and &lt;code&gt;argon2-cffi&lt;/code&gt;, which wrap audited libraries. ATLOCK's own container format and key handling have &lt;em&gt;not&lt;/em&gt; been independently reviewed. The self-test and fuzzer are mine, not an audit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python can't reliably wipe secrets from RAM.&lt;/strong&gt; Keys and passwords can linger in memory or swap. It's in the docs now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It protects data at rest.&lt;/strong&gt; It won't save you from malware already running as you, a keylogger, or a weak password.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A short threat model now ships in the docstring too.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔓 The part where you come in
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ATLOCK v5 is finished, but it isn't public yet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm releasing it when Akhouri Systems crosses &lt;strong&gt;1,000 downloads&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Akhouri Systems downloads
[█████████████████████████████░░░] 940 / 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;60 downloads.&lt;/strong&gt; That's all that stands between you and v5.&lt;/p&gt;

&lt;p&gt;You can grab the current public version, &lt;strong&gt;ATLOCK v4&lt;/strong&gt;, right now:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://fn6qtj.s.gy/ATLOCK-v4" rel="noopener noreferrer"&gt;Download ATLOCK v4&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's why I'm asking you to try it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You help unlock v5.&lt;/strong&gt; Every download moves the bar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You'll know exactly what v5 improves.&lt;/strong&gt; Everything above is going into it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your feedback shapes the release.&lt;/strong&gt; Reviewers like the one who roasted me are the reason v5 is better than the post I originally wrote.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  💬 How to help (30 seconds)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⬇️ &lt;strong&gt;Download v4&lt;/strong&gt; and break something&lt;/li&gt;
&lt;li&gt;⭐ &lt;strong&gt;Star the repo&lt;/strong&gt; so more people find it: &lt;a href="https://github.com/Akhouri-Anmol-Kumar" rel="noopener noreferrer"&gt;github.com/Akhouri-Anmol-Kumar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🗨️ &lt;strong&gt;Comment below&lt;/strong&gt; with the one thing you'd attack first. If it's good, I'll test it on my own files and write up the result, the way I did here.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you're the reviewer who started all this: thank you. You made v5 better, and I mean that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See you at 1,000.&lt;/strong&gt; 🔐&lt;/p&gt;

</description>
      <category>security</category>
      <category>python</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Built a Desktop Image Toolkit in Python — One App, Six Workspaces, Zero Browser Tabs 🖼️</title>
      <dc:creator>Akhouri Anmol Kumar</dc:creator>
      <pubDate>Fri, 02 Oct 2026 06:00:31 +0000</pubDate>
      <link>https://dev.to/akhourianmolkumar/i-built-a-desktop-image-toolkit-in-python-one-app-six-workspaces-zero-browser-tabs-2fnm</link>
      <guid>https://dev.to/akhourianmolkumar/i-built-a-desktop-image-toolkit-in-python-one-app-six-workspaces-zero-browser-tabs-2fnm</guid>
      <description>&lt;p&gt;&lt;strong&gt;What if image editing, format conversion, compression, and image search didn't require juggling multiple websites and applications?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That question is part of what led me to build &lt;strong&gt;APIC — Advanced Image Processing Center&lt;/strong&gt;, an image-processing desktop application developed under &lt;strong&gt;Akhouri Systems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And no, this isn't another article that just says, “I built an app, please download it.”&lt;/p&gt;

&lt;p&gt;Let's look at the actual application architecture, the UI design, the workflow decisions, and why I'd like developers to put APIC through its paces.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ First, what is APIC?
&lt;/h2&gt;

&lt;p&gt;APIC is a desktop application built with &lt;strong&gt;Python and PyQt6&lt;/strong&gt;. Its goal is to bring several image-related workflows into a single desktop interface.&lt;/p&gt;

&lt;p&gt;Instead of jumping between separate tools, APIC organizes its functionality into dedicated workspaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧰 Meet the six workspaces
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workspace&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🏠 Home&lt;/td&gt;
&lt;td&gt;Starting point for opening images and accessing workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✏️ Edit&lt;/td&gt;
&lt;td&gt;Image-editing workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔄 Convert&lt;/td&gt;
&lt;td&gt;Image conversion workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📦 Compress&lt;/td&gt;
&lt;td&gt;Image compression workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔎 Search&lt;/td&gt;
&lt;td&gt;Dedicated image-search workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ℹ️ About&lt;/td&gt;
&lt;td&gt;Application information and product details&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The idea is simple: &lt;strong&gt;one application, separate workflows, consistent navigation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You don't need to learn an entirely different interface every time you switch tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Under the hood: How APIC is structured
&lt;/h2&gt;

&lt;p&gt;Here's where things get interesting from a development perspective.&lt;/p&gt;

&lt;p&gt;APIC isn't built as one enormous window with every feature crammed into it. Its main window coordinates separate screens and switches between them.&lt;/p&gt;

&lt;p&gt;The application uses Python with PyQt6, including &lt;code&gt;QMainWindow&lt;/code&gt;, &lt;code&gt;QStackedWidget&lt;/code&gt;, layouts, buttons, signals, and slots.&lt;/p&gt;

&lt;p&gt;The high-level structure looks 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;APIC
│
├── Main Window
│   ├── Sidebar Navigation
│   ├── Stacked Content Area
│   └── Status Bar
│
├── Home Screen
├── Edit Mode
├── Convert Mode
├── Compress Mode
├── Search Mode
└── About Screen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main window creates the individual screens and registers them in a dictionary. The &lt;code&gt;QStackedWidget&lt;/code&gt; holds those screens, while the sidebar tells the application which screen to display.&lt;/p&gt;

&lt;p&gt;For example, the navigation logic follows this pattern:&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;def&lt;/span&gt; &lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_screens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_current_mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCurrentWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_screens&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_active&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why is this useful?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separation of concerns:&lt;/strong&gt; Each workspace has its own module.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized navigation:&lt;/strong&gt; The main window controls screen switching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability:&lt;/strong&gt; Changes to one workspace can often be isolated from the others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent UI:&lt;/strong&gt; The sidebar and status bar remain part of the main application shell.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a practical example of organizing a desktop application into manageable components rather than letting the main window become responsible for everything.&lt;/p&gt;

&lt;p&gt;Of course, modularity alone doesn't guarantee good software. Each module still needs proper error handling, testing, and clear interfaces.&lt;/p&gt;

&lt;p&gt;But it's a useful architectural foundation.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔀 One interesting design decision: File routing
&lt;/h2&gt;

&lt;p&gt;Opening an image sounds trivial until an application needs to decide what to do with one file versus several.&lt;/p&gt;

&lt;p&gt;APIC handles these cases differently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open one image:&lt;/strong&gt; The application records the file in its recent-file list, loads it into Edit Mode, and navigates to that workspace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open multiple images:&lt;/strong&gt; The selected paths are added to Convert Mode, and the application switches to the converter.&lt;/p&gt;

&lt;p&gt;Here's the simplified decision:&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;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;home_screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_recent_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;edit_mode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;edit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_mode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;convert&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a small piece of code, but it demonstrates an important UX principle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The application should respond to the user's workflow, not force the user to navigate manually after every action.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A developer building a media manager, document utility, or batch-processing application could apply the same pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⌨️ Keyboard shortcuts aren't an afterthought
&lt;/h2&gt;

&lt;p&gt;A desktop application should work well for mouse users and keyboard-oriented users.&lt;/p&gt;

&lt;p&gt;APIC includes global shortcuts for opening files and navigating between workspaces.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Shortcut&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl + O&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Open images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl + 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Home&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl + 2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Edit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl + 3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Convert&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl + 4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl + 5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;About&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These shortcuts are implemented using PyQt6's &lt;code&gt;QShortcut&lt;/code&gt; and &lt;code&gt;QKeySequence&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&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="n"&gt;shortcuts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ctrl+O&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_global_open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ctrl+1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;home&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ctrl+2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;edit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ctrl+3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;convert&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ctrl+4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;compress&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ctrl+5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;F1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;about&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that navigation shortcuts reuse the same navigation function as the sidebar.&lt;/p&gt;

&lt;p&gt;That means both input methods follow the same screen-switching logic instead of implementing separate navigation behavior.&lt;/p&gt;

&lt;p&gt;It's a small detail, but small details accumulate into a more consistent application.&lt;/p&gt;




&lt;h2&gt;
  
  
  🖱️ Drag, drop, and supported formats
&lt;/h2&gt;

&lt;p&gt;APIC also supports opening images through drag-and-drop.&lt;/p&gt;

&lt;p&gt;The main window checks whether the incoming event contains URLs, accepts the proposed drop action, and extracts local file paths when the files are dropped.&lt;/p&gt;

&lt;p&gt;The code filters the dropped files using their extensions.&lt;/p&gt;

&lt;p&gt;The supported extensions include:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PNG&lt;/code&gt; · &lt;code&gt;JPG&lt;/code&gt; · &lt;code&gt;JPEG&lt;/code&gt; · &lt;code&gt;WEBP&lt;/code&gt; · &lt;code&gt;BMP&lt;/code&gt; · &lt;code&gt;TIFF&lt;/code&gt; · &lt;code&gt;TIF&lt;/code&gt; · &lt;code&gt;GIF&lt;/code&gt; · &lt;code&gt;ICO&lt;/code&gt; · &lt;code&gt;HEIC&lt;/code&gt; · &lt;code&gt;AVIF&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The file dialog uses a corresponding image-file filter.&lt;/p&gt;

&lt;p&gt;One technical distinction worth understanding: accepting a file extension doesn't automatically guarantee that every image encoded in that format can be decoded on every machine. Actual support depends on the image-loading and processing implementation and its available codecs.&lt;/p&gt;

&lt;p&gt;That's precisely the kind of thing I'd like testers to investigate.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎨 The interface matters, too
&lt;/h2&gt;

&lt;p&gt;A utility can be technically functional and still be frustrating to use.&lt;/p&gt;

&lt;p&gt;APIC uses a dedicated sidebar, a stacked content area, a dark-theme stylesheet, and a status bar. The sidebar separates navigation from the workspace itself, allowing the active task to occupy the main content area.&lt;/p&gt;

&lt;p&gt;The application also connects status-message signals from its workspaces to the main window's status bar.&lt;/p&gt;

&lt;p&gt;In practical terms, that gives individual workspaces a way to communicate status information without requiring each one to manage the main window's status bar independently.&lt;/p&gt;

&lt;p&gt;The result is a desktop-oriented structure rather than a website wrapped inside an application window.&lt;/p&gt;

&lt;p&gt;And yes, there's still room to improve it. That's why real-world feedback matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Here's where you come in: Test APIC
&lt;/h2&gt;

&lt;p&gt;I don't want you to download APIC, open it once, and forget about it.&lt;/p&gt;

&lt;p&gt;I want developers, students, designers, and people who work with images to actually try it.&lt;/p&gt;

&lt;p&gt;If you decide to test APIC, here are a few useful experiments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open a single image and inspect the Edit workflow.&lt;/li&gt;
&lt;li&gt;Select multiple images and inspect how the application routes them to Convert Mode.&lt;/li&gt;
&lt;li&gt;Try the keyboard shortcuts instead of clicking the sidebar.&lt;/li&gt;
&lt;li&gt;Test drag-and-drop with different supported image formats.&lt;/li&gt;
&lt;li&gt;Check how the application responds to invalid paths, unreadable files, or unusual image dimensions.&lt;/li&gt;
&lt;li&gt;Look for interface inconsistencies, unexpected behavior, and workflow friction.&lt;/li&gt;
&lt;li&gt;If you encounter a bug, report the steps needed to reproduce it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please don't assume that every feature is flawless just because it has a dedicated screen. The real question is how reliably each workflow behaves under actual use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful bug reports are more valuable than vague feedback.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If something breaks, tell me what you did, what you expected, and what actually happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  📥 Ready to try APIC?
&lt;/h2&gt;

&lt;p&gt;You can get the application here:&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 &lt;a href="https://github.com/Akhouri-Anmol-Kumar/APIC/releases/download/APIC/APIC.zip" rel="noopener noreferrer"&gt;DOWNLOAD APIC — Advanced Image Processing Center&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Want to inspect the project first?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Akhouri-Anmol-Kumar/APIC" rel="noopener noreferrer"&gt;Explore the APIC source repository on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Download the application, explore its workspaces, and see how it fits your workflow.&lt;/p&gt;

&lt;p&gt;If you're a Python developer, I'd especially like to hear your thoughts on the PyQt6 architecture, navigation design, file handling, and areas that need improvement.&lt;/p&gt;




&lt;h2&gt;
  
  
  👨‍💻 A little about the developer
&lt;/h2&gt;

&lt;p&gt;I'm Akhouri Anmol Kumar, founder of &lt;strong&gt;Akhouri Systems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I build software with a focus on practical desktop utilities, straightforward workflows, and applications that people can actually use.&lt;/p&gt;

&lt;p&gt;APIC is one of those projects: take a common category of work, organize it into a coherent interface, and keep improving it through real usage and feedback.&lt;/p&gt;

&lt;p&gt;I'm still learning, building, testing, and refining.&lt;/p&gt;

&lt;p&gt;And I believe independent software becomes more useful when developers invite people to examine it critically instead of treating every release as a finished masterpiece.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 Let's talk image-processing workflows
&lt;/h2&gt;

&lt;p&gt;I have three questions for developers and people who work with images:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which image-processing tasks do you perform most often: editing, converting, compressing, or something else?&lt;/li&gt;
&lt;li&gt;What's one feature you wish more desktop image tools offered?&lt;/li&gt;
&lt;li&gt;If you try APIC, what's the first thing you'd improve?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Drop your thoughts in the comments. If you find a reproducible bug, please include the steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it. Explore it. Challenge it. Help me make it better.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If APIC proves useful in your workflow, a GitHub star or a share with another developer would also help the project reach more people.&lt;/p&gt;

&lt;p&gt;Thanks for reading. 🚀&lt;/p&gt;




</description>
      <category>python</category>
      <category>productivity</category>
      <category>showdev</category>
      <category>community</category>
    </item>
  </channel>
</rss>
