<?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: Marcin Firmuga</title>
    <description>The latest articles on DEV Community by Marcin Firmuga (@huckler).</description>
    <link>https://dev.to/huckler</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%2F3693207%2F6a4682e6-273e-4a98-9ce7-653391a5abcc.png</url>
      <title>DEV Community: Marcin Firmuga</title>
      <link>https://dev.to/huckler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/huckler"/>
    <language>en</language>
    <item>
      <title>Your PC Monitor Shows Numbers. It Should Understand Your Machine - Marcin Firmuga</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Tue, 16 Jun 2026 12:38:17 +0000</pubDate>
      <link>https://dev.to/huckler/your-pc-monitor-shows-numbers-it-should-understand-your-machine-marcin-firmuga-4mm2</link>
      <guid>https://dev.to/huckler/your-pc-monitor-shows-numbers-it-should-understand-your-machine-marcin-firmuga-4mm2</guid>
      <description>&lt;p&gt;Your PC monitor shows numbers. It should understand your machine.&lt;/p&gt;

&lt;p&gt;I wrote most of this article in the evening, after a day of welding plastics at a repair shop.&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.amazonaws.com%2Fuploads%2Farticles%2Fr3aj3ju8jwt3a2s1el5t.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.amazonaws.com%2Fuploads%2Farticles%2Fr3aj3ju8jwt3a2s1el5t.png" alt=" " width="605" height="812"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's the honest setup. My savings ran out.&lt;/strong&gt;&lt;br&gt;
My IT applications stay silent. So three days ago I started a temporary job that has nothing to do with code, and I write this at night, &lt;strong&gt;&lt;em&gt;the same rhythm this whole project was built in for 11 months.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But here's the part that keeps me going:&lt;/strong&gt;&lt;br&gt;
the thing I'm about to explain isn't a plan or a pitch.&lt;/p&gt;

&lt;p&gt;It's working code in a free, open-source tool you can download right now and read line by line. Industrial-grade statistics, running on your PC, learning your specific machine.&lt;br&gt;
Built by someone who codes between shifts.&lt;/p&gt;

&lt;p&gt;Let me show you why every traditional PC monitor is fundamentally limited  and what learning your specific hardware actually looks like in code.&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.amazonaws.com%2Fuploads%2Farticles%2Fn8t7x77ezzyqhxbpt39b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn8t7x77ezzyqhxbpt39b.gif" alt=" " width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The threshold is dumb by design
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Open any popular system monitor and it does one thing:&lt;/strong&gt;&lt;br&gt;
draws 78°C on a graph. Red when it crosses 80. That's it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It has no idea whether that 78°C is your idle on a hot July afternoon, or gaming on a cooler that's been collecting dust for six months. To the monitor, 78 is just 78.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The threshold is dumb by design.&lt;br&gt;
&lt;strong&gt;That's not an insult but it's its nature.&lt;/strong&gt;&lt;br&gt;
Rule&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"if temp &amp;gt; X, alert"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;has no concept of what it's running on. It doesnt remember yesterday.&lt;br&gt;
It doesn't know your &lt;strong&gt;RTX always holds 71°C in this game&lt;/strong&gt;, and today it s*&lt;em&gt;uddenly hits 77 at the same load in the same room&lt;/em&gt;*.&lt;br&gt;
The threshold only sees a number against a constant somebody hardcoded for every machine in the world at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And here's the most important sentence in this article:&lt;/strong&gt;&lt;br&gt;
your machine isn't in any table.&lt;/p&gt;
&lt;h2&gt;
  
  
  How these tools actually work
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Before anyone says "but I have Afterburner and it's great" — sure, it is.&lt;br&gt;
Let's just look at what it actually does under the hood.&lt;br&gt;
And what the others do, because each one is excellent at one thing and blind in another.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;MSI Afterburner / RivaTuner:&lt;/strong&gt;&lt;br&gt;
a hand-drawn fan curve (lookup table) and a fixed clock/voltage offset.&lt;br&gt;
Zero learning. The curve is a table.&lt;br&gt;
"Set and forget" OC doesn't know about silicon aging or ambient temperature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fan Control / Argus Monitor:&lt;/strong&gt;&lt;br&gt;
highly configurable, but still rules and triggers that YOU define.&lt;br&gt;
You are the intelligence. The program just executes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HWiNFO / HWMonitor:&lt;/strong&gt; the gold standard for raw sensor data.&lt;br&gt;
Zero recommendations, zero memory. Pure readout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CCleaner:&lt;/strong&gt; deletes temp files and "cleans the registry".&lt;br&gt;
Registry cleaning is a 2026 myth, Microsoft itself advises against it, performance gain is roughly zero.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GeForce Experience / Armoury Crate / iCUE:&lt;/strong&gt;&lt;br&gt;
cloud database of GPU+game, presets by hardware category.&lt;br&gt;
A profile for "RTX 4070," not for your specific card or your temperatures. Phones home.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notice the pattern.&lt;/strong&gt;&lt;br&gt;
Every one is a different way to do the same two things:&lt;br&gt;
show data, or execute a rule somebody set in advance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;None of them builds a model of your computer.&lt;/strong&gt;&lt;br&gt;
At best, you are the intelligence, sitting there setting curves by hand.&lt;br&gt;
At worst, the cloud is the intelligence, it knows you have an "RTX 4070" and has no clue your specific unit runs 6 degrees hotter than your neighbor's with the same SKU.&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.amazonaws.com%2Fuploads%2Farticles%2Fcv0bo9muqammixlq085a.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.amazonaws.com%2Fuploads%2Farticles%2Fcv0bo9muqammixlq085a.png" alt=" " width="416" height="322"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Four reasons "general" is weak
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Silicon lottery.&lt;/strong&gt;&lt;br&gt;
Two identical RTX 4070s from the same production line aren't identical.&lt;br&gt;
Different voltage-frequency curves, different leakage, different undervolt headroom. &lt;strong&gt;Gap can reach 50-100 mV&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That forum advice "&lt;em&gt;for a 4070 do -100 mV, works for me&lt;/em&gt;" will crash half the units to a black screen, because half don't have that headroom.&lt;br&gt;
A general profile physically cannot know your silicon.&lt;br&gt;
It saw an averaged card you don't own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aging and drift.&lt;/strong&gt;&lt;br&gt;
Thermal paste pumps out over a year or three, and temperatures climb a few degrees. Fan bearings wear. PSU capacitors age and lose capacitance.&lt;br&gt;
A fixed profile never adapts, because it was written once.&lt;br&gt;
Your "stable" OC from last year throws silent soft-errors today.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ambient and context.&lt;/strong&gt;&lt;br&gt;
The same load at 18°C in winter and 28°C in summer produces different core temperatures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"if temp &amp;gt; X"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rule is blind to this. It doesn't know your room, the season, or that you opened a window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load composition.&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;"Game + Discord + browser + OBS" is a completely different thermal profile than the game alone.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A Blender render (sustained 100% for an hour) behaves differently than a game (bursty spikes) and differently than a crypto miner (pegged full).&lt;br&gt;
General thresholds treat load as if it exists in isolation.&lt;br&gt;
In real life it never does.&lt;/p&gt;
&lt;h2&gt;
  
  
  Voltages. This is where it all comes together.
&lt;/h2&gt;

&lt;p&gt;If you remember one example from this article, remember this one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The ATX spec for the 12V rail allows ±5%.&lt;/strong&gt; So anything from 11.4V to 12.6V is formally "within norm".&lt;br&gt;
Every classic monitor only alerts you once voltage leaves that band.&lt;/p&gt;

&lt;p&gt;But a healthy PSU doesn't float across that whole range.&lt;br&gt;
A healthy PSU holds your rail much, much tighter, around 11.95-12.05V. That's a real ±0.4%, not ±5%.&lt;/p&gt;

&lt;p&gt;Now: your PSU starts aging.&lt;br&gt;
Under load the rail drops to 11.7V.&lt;br&gt;
Still "&lt;strong&gt;&lt;em&gt;in spec&lt;/em&gt;&lt;/strong&gt;"! The threshold says OK, you're fine.&lt;br&gt;
But those are tired capacitors making themselves known, months, sometimes half a year before the system starts failing under heavier load.&lt;/p&gt;

&lt;p&gt;This is where statistics computed on your history come in, not on a spec sheet.&lt;br&gt;
PC Workman keeps the median and MAD (median absolute deviation) of your own samples and computes a modified Z-score per &lt;strong&gt;Iglewicz&lt;/strong&gt;-&lt;strong&gt;Hoaglin&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;M = 0.6745 × (x − median) / MAD
|M| &amp;gt; 3.5  → anomaly
|M| &amp;gt; 2.5  → warning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A drop to 11.7V, invisible to the ATX threshold, runs well past 3.5 against your own 11.95-12.05V norm. &lt;strong&gt;&lt;em&gt;Anomaly&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An early warning no threshold on earth catches, because the threshold looks at the manufacturer's spec, not at how this specific PSU behaved over the last few weeks.&lt;/p&gt;

&lt;p&gt;Why median, not mean? Because the mean is a coward.&lt;br&gt;
One voltage spike drags the mean up, widens the band, and the next spike passes without an alarm, the tool anesthetizes itself.&lt;/p&gt;

&lt;p&gt;The median doesn't move after one outlier.&lt;br&gt;
MAD inherits that robustness.&lt;br&gt;
Add four Nelson Rules (single spike, 2-of-3 cluster, nine points on one side, six-point monotonic trend), that's &lt;strong&gt;classic Statistical Process Control&lt;/strong&gt;, the same kind factories have used to watch production lines for decades.&lt;br&gt;
I'm not reinventing the wheel.&lt;br&gt;
I moved proven process control onto your PC's power rail.&lt;/p&gt;

&lt;p&gt;That's the whole thesis in one picture: an absolute spec threshold versus statistical control against your own history.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wait, "AI," meaning what exactly?
&lt;/h2&gt;

&lt;p&gt;I have to say this plainly, or the whole article goes in the trash with the marketing nonsense:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"AI" here does not mean a chatbot bolted onto an old tool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's no GPT stapled on that "intelligently analyzes your hardware" and in practice makes things up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Underneath sits real statistics:&lt;/strong&gt; **Welford's **algorithm for online mean and variance (one pass, no keeping the whole history in RAM), median and MAD for voltages, Nelson Rules, process control.&lt;/p&gt;

&lt;p&gt;These are methods from the '60s and '90s, boring, predictable, and that's exactly why I trust them.&lt;br&gt;
Statistics don't hallucinate.&lt;/p&gt;

&lt;p&gt;When someone says "AI in a monitor," 95% of the time it means&lt;br&gt;
"we pasted in an API and now it costs more".&lt;br&gt;
&lt;strong&gt;Here it's the opposite, the model learns locally, on your data, with no account and nothing sent anywhere.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The six lines that start it all
&lt;/h2&gt;

&lt;p&gt;The whole context-aware system begins with one tiny function. This is the actual code:&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;classify&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;cpu_pct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gpu_pct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&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;gpu_pct&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gaming&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;cpu_pct&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;idle&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;cpu_pct&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;light&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;cpu_pct&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;medium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;heavy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Five contexts:&lt;/strong&gt; &lt;em&gt;gaming, idle, light, medium, heavy&lt;/em&gt;.&lt;br&gt;
That's the secret.&lt;/p&gt;

&lt;p&gt;Once the system knows the context, it learns what "normal" means inside it.&lt;br&gt;
Not normal in general.&lt;br&gt;
Normal for your machine, doing what it's doing right now.&lt;br&gt;
Each snapshot lands in one of five buckets, and each bucket keeps its own learned baseline using **Welford's **online algorithm over your last 14 days of history.&lt;/p&gt;

&lt;p&gt;An 80°C threshold for everything is lazy.&lt;br&gt;
72°C while gaming on a mid-tower is fine.&lt;br&gt;
&lt;strong&gt;The same 72°C while idle on a thin laptop means something is wrong.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it actually beats the threshold
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Predictive maintenance&lt;/strong&gt;, the killer feature.&lt;br&gt;
Voltage drift caught by MAD and Nelson Rules means tired capacitors.&lt;br&gt;
A systematic +3-5°C climb over weeks means paste needs replacing, caught before the CPU throttles.&lt;br&gt;
Falling RPM-to-temperature efficiency means dust in the heatsink.&lt;br&gt;
Catching problems before they become problems.&lt;br&gt;
A threshold can't do this by definition, it waits until things are already bad.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root-cause throttling&lt;/strong&gt; instead of "CPU hot".&lt;br&gt;
A general tool says: 95°C, a lot.&lt;br&gt;
&lt;strong&gt;The model says:&lt;/strong&gt; 95°C, but only during game+render, and that's +6°C above your 30-day norm for this specific load, most likely dust or paste, here's the trend chart, see for yourself.&lt;br&gt;
The second answer contains a cause.&lt;br&gt;
The first is just a number with an exclamation mark.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anomaly as security.&lt;/strong&gt; A process pretending to be svchost.exe but launched from %TEMP%.&lt;br&gt;
An unusual CPU pattern that looks like a quiet miner.&lt;br&gt;
Pattern-against-your-norm catches things a signature list doesn't know, because you don't need to know the threat's name, you just need to know this machine never behaved like this before.&lt;/p&gt;

&lt;h2&gt;
  
  
  The analogy that closes it
&lt;/h2&gt;

&lt;p&gt;Whoop and Garmin don't tell you&lt;br&gt;
"your resting heart rate is 60, norm is 60-100, you're OK".&lt;br&gt;
They learn your resting HR and HRV, and alert when you drift from your baseline, even if you're still within "population norm".&lt;br&gt;
&lt;strong&gt;That's how they catch something happening a day before you feel it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PC Workman is exactly that, for your computer.&lt;br&gt;
"78°C" without your baseline is like a heart rate of 100 without knowing whether you're looking at a marathon runner after training or someone who just climbed to the second floor out of breath.&lt;br&gt;
&lt;strong&gt;Same number, two completely different worlds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The whole difference is context — and a threshold has none.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honestly: where this has limits
&lt;/h2&gt;

&lt;p&gt;I won't sell you this as magic, because it isn't, and a text pretending its product has no flaws disqualifies itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cold-start.&lt;/strong&gt; Fresh after install,&lt;br&gt;
the model doesn't know your norm yet, it has to gather data for weeks, realistically 6-12 months, to pass through summer and winter, gaming and idle, different loads.&lt;/p&gt;

&lt;p&gt;During that time it's closer to a regular monitor than an intelligent one. That's the price of later talking about your hardware instead of an averaged one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It needs good sensors&lt;/strong&gt;, and Windows can really make you suffer here.&lt;br&gt;
psutil.sensors_temperatures() returns an empty field on Windows, no temperatures, the end, thank you.&lt;br&gt;
Hence the dependency on LibreHardwareMonitor and WMI just to have something to learn from. I know this not from documentation but from tripping over it myself and losing an evening before I understood why the voltage chart was empty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It must not bark without reason.&lt;/strong&gt;&lt;br&gt;
One false alarm now and then and you stop trusting the tool, you turn off notifications and that's that.&lt;br&gt;
So 12V spikes during GPU load changes are deliberately suppressed&lt;br&gt;
(they're physically expected, not a failure)&lt;br&gt;
and a pattern that repeats five times stops being treated as an anomaly and becomes your hardware's new norm.&lt;br&gt;
A*&lt;em&gt;nomaly decay.&lt;/em&gt;*&lt;br&gt;
A tool that learns must also know how to retract its own alarm.&lt;/p&gt;

&lt;h2&gt;
  
  
  And one more thing, to be clear:
&lt;/h2&gt;

&lt;p&gt;this is not &lt;strong&gt;anti-HWiNFO&lt;/strong&gt; or &lt;strong&gt;anti-Afterburner&lt;/strong&gt;. Raw sensor data is still the foundation everything stands on. What changes isn't that you read the data, it's what happens to that data next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm telling you this between welding shifts
&lt;/h2&gt;

&lt;p&gt;Your computer has a history. Specific, physical, its own, that one piece of silicon in that one room with that one PSU.&lt;br&gt;
It's time a program remembered it, instead of comparing you to an average you never owned.&lt;/p&gt;

&lt;p&gt;I built this because I got tired of tools that show and never understand. I built it on a laptop that hit 94°C, between warehouse shifts in the Netherlands, then between convenience store shifts in Poland, and now between welding shifts at a repair shop.&lt;/p&gt;

&lt;p&gt;Monday, an article about this project hit #1 Trending on HackerNoon.&lt;br&gt;
&lt;strong&gt;My first thought wasn't "I made it".&lt;br&gt;
It was "what if this is an accident?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fear after success is stranger than fear after failure, with failure you know what to fix, with success you suddenly have something to lose.&lt;/p&gt;

&lt;p&gt;But the code doesn't know I'm scared. It doesn't check trending positions.&lt;br&gt;
It classifies the context and keeps learning. Maybe that's the lesson.&lt;/p&gt;

&lt;p&gt;We stopped needing a tool that shows. We need one that understands,&lt;br&gt;
and does the work for us.&lt;br&gt;
Locally. Quietly.&lt;/p&gt;




&lt;p&gt;This isn't a roadmap, it's working code.&lt;br&gt;
Thermal Baseline Learning and Voltage SPC described above run in&lt;br&gt;
PC Workman v1.7.9 - free, open-source. You can check every line.&lt;/p&gt;

&lt;p&gt;Download or read the code:&lt;br&gt;
&lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;github.com/HuckleR2003/PC_Workman_HCK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full article on the project domain site!: &lt;a href="https://pcworkman.dev" rel="noopener noreferrer"&gt;pcworkman.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything else and coffee! :) : &lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;linktr.ee/marcin_firmuga&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.amazonaws.com%2Fuploads%2Farticles%2Fovqxebar2788y7fz384t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovqxebar2788y7fz384t.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;About the Author&lt;br&gt;
I’m Marcin Firmuga. Solo developer and founder of HCK_Labs.&lt;/p&gt;

&lt;p&gt;I created PC Workman, an open-source, AI-powered PC resource monitor who learns, after time, your natural PC behavior (spikes, voltage, temps, usages) built entirely from scratch on dying hardware during warehouse shifts in the Netherlands.&lt;/p&gt;

&lt;p&gt;Before this: game translations, PC technician internships, warehouse operations in multiple countries, and countless failed projects I never finished.&lt;/p&gt;

&lt;p&gt;But this one? This one stuck.&lt;br&gt;
1000+ hours of code. 4 complete UI rebuilds. 16,000 lines deleted.&lt;br&gt;
3 AM all-nighters.Energy drinks and toast.&lt;/p&gt;

&lt;p&gt;And my own hck_GPT AI, building for months to give a PC Workman a brain and heart.&lt;br&gt;
And finally, an app I wouldn’t close in 5 seconds. That’s the difference between building and shipping.&lt;/p&gt;

&lt;p&gt;Marcin Firmuga | 22 | Poland | HCK_Labs Building PC Workman publicly. Physical work by day, code by night.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Marcin Firmuga | 22 | Poland | HCK_Labs&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Building PC Workman publicly. Physical work by day, code by night.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>ai</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Was Supposed to Fix Bugs. I Accidentally Built Two Features Instead. PC Workman 1.7.8 - Advanced Deep Learning AI, Supply Monitor and Health Keeper.</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Fri, 05 Jun 2026 19:44:00 +0000</pubDate>
      <link>https://dev.to/huckler/i-was-supposed-to-fix-bugs-i-accidentally-built-two-features-instead-pc-workman-178-advanced-a83</link>
      <guid>https://dev.to/huckler/i-was-supposed-to-fix-bugs-i-accidentally-built-two-features-instead-pc-workman-178-advanced-a83</guid>
      <description>&lt;h1&gt;
  
  
  I Was Supposed to Fix Bugs. I Accidentally Built Two Features Instead.
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Friday Shipped &amp;amp; Scarred #11&lt;/strong&gt;, the one where "no new features" lasted about 4 hours.&lt;/p&gt;




&lt;p&gt;The plan after v1.7.7 (which shipped 20+ patches over one week): &lt;strong&gt;maintenance only&lt;/strong&gt;. Fix the tester list. Test things.&lt;br&gt;
&lt;strong&gt;Don't build anything.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I opened Setup &amp;amp; Drivers to verify a fix. My own PC had two GPU entries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RTX&lt;/strong&gt; - the one currently in the machine.&lt;br&gt;
And &lt;strong&gt;GT 1030&lt;/strong&gt; - removed over two years ago.&lt;br&gt;
Driver entries still in the registry, taking up space, doing nothing. Windows keeps dead hardware on life support forever.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I thought: if MY machine has this, everyone's does.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Three hours later, Ghost Driver Detection was in the codebase.&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.amazonaws.com%2Fuploads%2Farticles%2F9ocmnikvrodisvp4e388.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.amazonaws.com%2Fuploads%2Farticles%2F9ocmnikvrodisvp4e388.png" alt=" " width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Ghost Drivers: Why WMI Lies To You
&lt;/h2&gt;

&lt;p&gt;The obvious approach for "which devices are actually connected" is WMI. It's wrong.&lt;/p&gt;

&lt;p&gt;WMI &lt;code&gt;Win32_PnPEntity&lt;/code&gt; returns phantom devices too, that's exactly the problem I was trying to detect. You can't ask the ghost if it's a ghost.&lt;/p&gt;

&lt;p&gt;What actually works: &lt;code&gt;pnputil /enum-devices --connected&lt;/code&gt;.&lt;br&gt;
PnPUtil queries the kernel's live device tree, not the registry cache.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# core/startup_watcher.py — _get_pnp_connected_names()
result = subprocess.run(
    ["pnputil", "/enum-devices", "--connected", "/class", guid],
    capture_output=True, timeout=10,
    creationflags=subprocess.CREATE_NO_WINDOW,
)
# Parse "Instance ID: ..." blocks - only hardware that's physically here right now

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  The detection logic is a set diff:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Registry drivers -&amp;gt; all installed entries for a device class&lt;/li&gt;
&lt;li&gt;Connected (pnputil) -&amp;gt; what's actually plugged in right now&lt;/li&gt;
&lt;li&gt;Gap -&amp;gt; ghost
Any driver entry older than 20 months not in the connected set gets flagged. Red badge. Age info.
&lt;strong&gt;One-click removal via pnputil /remove-device.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The feature shipped fast because the registry-reading infrastructure for the Drivers tab already existed.&lt;/strong&gt;&lt;br&gt;
I just needed the diff logic and a new card in Optimization Center.&lt;/p&gt;
&lt;h3&gt;
  
  
  Background App Hibernation:
&lt;/h3&gt;

&lt;p&gt;Two Modes, Different Tradeoffs&lt;br&gt;
Feature #14 of 16 planned for Optimization Center. Started as a bug investigation into idle process detection, turned into a full feature.&lt;/p&gt;
&lt;h3&gt;
  
  
  Detecting "idle" without false positives
&lt;/h3&gt;

&lt;p&gt;The naive version: flag any process with CPU &amp;lt; 1% for 15 minutes. Problem: that includes background services, compiler daemons, git processes — anything that legitimately idles. The user shouldn't see those.&lt;/p&gt;

&lt;p&gt;The actual filter in app_activity_tracker.py:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Only surface apps that were ever in the foreground this session.
# If it was never in the foreground, it's a service — skip it.
if pid not in known_fg_pids:
    continue

# CPU guard: need 3 consecutive samples all below CPU_IDLE_PCT = 3.0%
# "below threshold" ≠ "not doing background work"
if len(samples) &amp;lt; CPU_SAMPLES_NEED:  # CPU_SAMPLES_NEED = 3
    continue
cpu_avg = sum(samples[-CPU_SAMPLES_NEED:]) / CPU_SAMPLES_NEED
if cpu_avg &amp;gt;= CPU_IDLE_PCT:
    continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The foreground window tracking uses&lt;br&gt;
&lt;strong&gt;GetForegroundWindow and GetWindowThreadProcessId via ctypes&lt;/strong&gt;, polled every 15 seconds. No external deps, just pure Windows API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@staticmethod
def _foreground_pid() -&amp;gt; int:
    hwnd = ctypes.windll.user32.GetForegroundWindow()
    pid  = ctypes.c_ulong(0)
    ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
    return pid.value
The two sleep behaviors
LOW PRIORITY — SetPriorityClass(IDLE_PRIORITY_CLASS) via kernel32.

IDLE_PRIORITY_CLASS = 0x00000040

def _set_priority(pid: int, priority_class: int) -&amp;gt; bool:
    h = ctypes.windll.kernel32.OpenProcess(PROCESS_SET_INFORMATION, False, pid)
    if not h:
        return False
    try:
        return bool(ctypes.windll.kernel32.SetPriorityClass(h, priority_class))
    finally:
        ctypes.windll.kernel32.CloseHandle(h)
Process still runs. Gets CPU scheduling only when everything else is idle. Safe for apps you might need soon — Discord, Spotify.

FREEZE — psutil.Process.suspend(), which calls NtSuspendProcess internally.

if behavior == "freeze":
    proc.suspend()   # NtSuspendProcess under the hood
else:
    _set_priority(pid, IDLE_PRIORITY_CLASS)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero CPU usage. Stays in RAM. Instant proc.resume() on wake. Good for things like updater processes that sit there all day doing nothing.&lt;/p&gt;

&lt;p&gt;Turbo integration&lt;br&gt;
The behaviors persist to hibernation_prefs.json per exe name. When TURBO mode activates (the existing power plan + service stop system in v1.7.7), hibernation behaviors apply automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# optimization_services.py — _tpp_run()
ok = _pp_set(_TPP["turbo_guid"])
if ok:
    _TPP["active"] = True
    hibm = COMPONENTS.get("core.hibernation_manager")
    if hibm:
        hibm.apply_turbo_behaviors()   # applies all configured per-exe behaviors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And reverses on Turbo deactivate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def _tpp_restore():
    ok = _pp_set(original_guid)
    if ok:
        _TPP["active"] = False
        hibm = COMPONENTS.get("core.hibernation_manager")
        if hibm:
            hibm.restore_turbo_apps()   # wakes everything that was frozen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Protected list of 30+ system process names (svchost.exe, MsMpEng.exe, dwm.exe, etc.) that never appear as hibernation candidates regardless of CPU or idle time.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Parser Bug That Corrupted Polish Words
&lt;/h2&gt;

&lt;p&gt;parser.py had an accent normalization step — a mapping of incomplete Polish fragments to their full forms, for users who don't type diacritics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_ACCENT_MAP = [
    ("temperatur",   "temperatura"),  # fix: "jak jest temperatur" → "temperatura"
    ("wydajnosc",    "wydajność"),
    ("pamieci",      "pamięci"),
    # ...
]

def _normalize_accents(self, text: str) -&amp;gt; str:
    for stripped, accented in self._ACCENT_MAP:
        text = text.replace(stripped, accented)  # ← THE BUG
    return text
"temperatur" is a substring of "temperatura". When a user typed "temperatura cpu" (the complete word), str.replace matched the fragment inside it:

"temperatura" → "temperaturaa"
The double-a broke every pattern match. "temperatura cpu" was routing to hw_cpu instead of temperature because the multi-word phrase "temperatura cpu" no longer matched anything in the vocabulary.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fix: word-boundary matching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def _normalize_accents(self, text: str) -&amp;gt; str:
    for stripped, accented in self._ACCENT_MAP:
        text = re.sub(r'\b' + re.escape(stripped) + r'\b', accented, text)
    return text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;\b only matches "temperatur" as a** standalone word*&lt;em&gt;. "temperatura" **passes through untouched.&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;This was caught during the 20-question intent routing test I ran post-audit.&lt;br&gt;
"temperatura cpu" was scoring hw_cpu with 33% confidence.&lt;br&gt;
Traced it to "temperaturaa cpu" matching nothing.&lt;/p&gt;

&lt;p&gt;The Cache That Was Rebuilding on Every Message&lt;br&gt;
Same file. Different problem. The folded pattern cache (used for accent-insensitive matching) was being built inside parse():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# OLD — runs on every single message
def parse(self, text):
    folded_patterns_cache = {
        intent: [self._ascii_fold(p) for p in patterns]
        for intent, patterns in INTENT_PATTERNS.items()
    }
    # ... scoring ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;INTENT_PATTERNS has 82 intents, some with 30+ patterns each. Every user message rebuilt this entire dict from scratch. O(n×m) per call.&lt;/p&gt;

&lt;p&gt;Fix: lazy class-level cache.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# NEW - built once, reused forever
class IntentParser:
    _folded_cache: Dict[str, List[str]] = {}

    def _get_folded_cache(self) -&amp;gt; Dict[str, List[str]]:
        if not self._folded_cache:
            IntentParser._folded_cache = {
                intent: [self._ascii_fold(p) for p in patterns]
                for intent, patterns in INTENT_PATTERNS.items()
            }
        return self._folded_cache
INTENT_PATTERNS is static at import time. There's no reason to rebuild it on message #47.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;82/82 - What Full Intent Coverage Actually Means&lt;br&gt;
The hck_GPT AI engine routes messages using a hybrid system:&lt;br&gt;
keyword scoring and Naive Bayes blend TO confidence score&lt;br&gt;
and rule engine if ≥ 0.65, Ollama LLM if below.&lt;/p&gt;

&lt;p&gt;Each intent has two config entries in hybrid_engine.py:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_CONTEXT_WINDOWS — how far back the AI looks for that intent type:

_CONTEXT_WINDOWS = {
    "hw_cpu":          5,      # last 5 minutes — live snapshot
    "temperature":     10,     # last 10 minutes
    "temp_comparison": 10080,  # last 7 days — trend comparison
    "weekly_trends":   10080,
    "session_digest":  480,    # 8-hour session summary
    "fan_speed":       5,
    # ... 82 total
}
_INTENT_HINTS - what Ollama is told to focus on per intent type:

_INTENT_HINTS = {
    "temperature":  "User is asking about system temperatures - be specific: CPU, GPU, and threshold warnings.",
    "temp_comparison": "User asks if PC is running hotter than usual - compare current temps to 7-day and 30-day historical averages.",
    "fan_speed":    "User is asking about fan RPM - show all fan sensors, current RPM, and if any fans are stalled.",
    "ram_flush":    "User wants to free up RAM - explain what's safe to close, give current top RAM consumers with MB values.",
    # ... 82 total
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before this week: 34/82 had context windows. 54/82 had hints. Every unregistered intent fell through to a 30-minute default window and empty guidance.&lt;/p&gt;

&lt;p&gt;Now all 82 have both. A query about "temperatur cpu" gets a 10-minute window (relevant recent data) and a hint telling the LLM exactly what to check.&lt;br&gt;
A trend query like "is my cpu hot more than average" (temp_comparison) gets 7 days of data and the right comparison guidance.&lt;/p&gt;

&lt;p&gt;The before/after on intent detection after fixing the parser&lt;br&gt;
bug and filling the maps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query   Before  After   Context
temperatur cpu  hw_cpu (broken) temperature ✓ 10m
is my pc more warm than normal? hw_all RULE 5m  temp_comparison ✓ 10080m
make roast about my pc  unknown fun_roast ✓   30m
morning brief   unknown morning_brief ✓   10080m
is my cpu overclocked?  hw_cpu  overclock_check ✓ 5m
Test suite after all changes: 21/21.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hck_GPT Panel Startup Bug&lt;br&gt;
One-liner symptoms: panel appears at the very top of the window on fresh launch. Toggle Max View Mode once and it snaps to the correct bottom position.&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.amazonaws.com%2Fuploads%2Farticles%2F3wkisp7poikz2cf5b8bu.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.amazonaws.com%2Fuploads%2Farticles%2F3wkisp7poikz2cf5b8bu.png" alt=" " width="730" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Root cause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parent.after(350, lambda: self._animate(0, self.collapsed_h, duration_ms=700))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The animation runs 350ms after panel creation. It reads parent.winfo_height() to compute y = parent_h - current_h.&lt;/p&gt;

&lt;p&gt;But 350ms isn't enough on the first launch - the window hasn't been laid out yet, so winfo_height() returns 0.&lt;br&gt;
&lt;strong&gt;Then y = 0 - 34 = -34, clamped to 0. Panel at the top.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Max View Mode triggered a geometry change, which forced a re-layout, which gave correct winfo_height().&lt;/p&gt;

&lt;p&gt;Fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def _animate(self, start_h, end_h, duration_ms=200, on_end=None):
    parent_h = self.parent.winfo_height()
    if parent_h &amp;lt; 50:
        # Window not rendered yet — retry in 80ms
        self.frame.after(80, lambda: self._animate(start_h, end_h, duration_ms, on_end))
        return
    # ... normal animation
Polls until the parent has an actual height. No arbitrary sleeps, no one-shot 350ms guess.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The Numbers
&lt;/h1&gt;

&lt;p&gt;2 unplanned features shipped (Ghost Drivers, Background App Hibernation)&lt;br&gt;
15/16 Optimization Center features live&lt;br&gt;
82/82 intents with context windows + LLM hints (was 34/54)&lt;br&gt;
14   vocabulary patterns fixed or added&lt;br&gt;
1   parser bug causing word corruption&lt;br&gt;
1   startup positioning bug in hck_GPT panel&lt;br&gt;
21/21 automated tests passing&lt;br&gt;
I was supposed to fix bugs. I fixed the bugs. I also shipped two features. I have no explanation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Stack &amp;amp; Links
&lt;/h1&gt;

&lt;p&gt;PC Workman is a real-time Windows system monitor with embedded AI assistant (hck_GPT). Open source, Python 3.9+ / Tkinter, Windows 10+.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/HuckleR2003/PC_Workman_HCK&lt;br&gt;
Medium (narrative version): &lt;a href="https://medium.com/@MarcinFirmuga/i-was-supposed-to-fix-bugs-i-accidentally-built-a-ghost-driver-detector-instead-pc-workman-1-7-8-395c7b927f8f" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;br&gt;
Support: &lt;a href="https://buycoffee.to/hcklabs" rel="noopener noreferrer"&gt;Coffee&lt;/a&gt; or &lt;a href="https://github.com/sponsors/HuckleR2003" rel="noopener noreferrer"&gt;Github&lt;/a&gt; :)&lt;br&gt;
Marcin Firmuga - HCK_Labs - solo dev, Poland.&lt;br&gt;
11 months. Still shipping.&lt;/p&gt;

&lt;h1&gt;
  
  
  About the Author
&lt;/h1&gt;

&lt;p&gt;I’m &lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;Marcin Firmuga&lt;/a&gt;. Solo developer and founder of HCK_Labs.&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.amazonaws.com%2Fuploads%2Farticles%2Ffhgwy1d2htmfiykxdkn2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhgwy1d2htmfiykxdkn2.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I created &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;PC Workman&lt;/a&gt;, an open-source, AI-powered PC resource monitor who learns, after time, your natural PC behavior (spikes, voltage, temps, usages) built entirely from scratch on dying hardware during warehouse shifts in the Netherlands.&lt;/p&gt;

&lt;p&gt;Before this: game translations, PC technician internships, warehouse operations in multiple countries, and countless failed projects I never finished.&lt;/p&gt;

&lt;p&gt;But this one? This one stuck.&lt;br&gt;
1000+ hours of code. 4 complete UI rebuilds. 16,000 lines deleted.&lt;br&gt;
3 AM all-nighters.Energy drinks and toast.&lt;/p&gt;

&lt;p&gt;And my own &lt;a href="https://github.com/HuckleR2003/hck-GPT" rel="noopener noreferrer"&gt;hck_GPT&lt;/a&gt; AI, building for months to give a PC Workman a brain and heart.&lt;br&gt;
And finally, an app I wouldn’t close in 5 seconds. That’s the difference between building and shipping.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Built an AI-Powered PC Monitor in Python. 28 Strangers Shaped Its Brain. PC Workman 1.7.6</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Thu, 28 May 2026 20:47:16 +0000</pubDate>
      <link>https://dev.to/huckler/i-built-an-ai-powered-pc-monitor-in-python-28-strangers-shaped-its-brain-pc-workman-176-l4d</link>
      <guid>https://dev.to/huckler/i-built-an-ai-powered-pc-monitor-in-python-28-strangers-shaped-its-brain-pc-workman-176-l4d</guid>
      <description>&lt;p&gt;I built an AI-powered PC monitor in Python. 28 strangers shaped its brain.&lt;br&gt;
This article is about PC Workman 1.7.6.&lt;br&gt;
But it's also about what indie dev actually looks like, between retail shifts, late night compiler sessions, and debugging Polish character encoding bugs at 4 AM.&lt;/p&gt;
&lt;h2&gt;
  
  
  Where it started
&lt;/h2&gt;

&lt;p&gt;PC Workman has created, when I live and work in Nederlands by Agency.&lt;br&gt;
Then 5 months later, I come back to Poland and trying to get a place for me.&lt;br&gt;
For 3 weeks I working by International Trucker.&lt;br&gt;
Then I got my little stop from coding, but after visits Slovakia and Czechy I have seen I carry a... 900% OVER MASS THAN LIMIT.&lt;br&gt;
I don't get anything, I just see that before next trip to France.&lt;br&gt;
Next&lt;br&gt;
I was working as a cashier. Coming home after 8-hour shifts and sitting down to code.&lt;/p&gt;

&lt;p&gt;Not because I had energy. Because I couldn't stop.&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.amazonaws.com%2Fuploads%2Farticles%2Fdp7st51hkpczdwsd24yn.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.amazonaws.com%2Fuploads%2Farticles%2Fdp7st51hkpczdwsd24yn.png" alt=" " width="800" height="1422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PC Workman started from one problem: my PC would slow down and I had no idea why. Task Manager said "CPU: 87%." But which process? Since when? How long? Nothing.&lt;/p&gt;

&lt;p&gt;Every monitoring tool was either outdated, required installing 3 extra libraries, or looked like it was designed in 2009 and nobody touched the code since.&lt;/p&gt;

&lt;p&gt;So I thought: I'll build my own.&lt;/p&gt;

&lt;p&gt;Classic mistake. Best decision I ever made.&lt;/p&gt;
&lt;h2&gt;
  
  
  10 months, 96 files, 48,000 lines
&lt;/h2&gt;

&lt;p&gt;Current state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Python files:     96
Total lines:      48,081
Response builder: 255,065 chars (yes, one file)
Process library:  241 entries
AI intents:       82
Response handlers: 65
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u0wcbv3t46r62yufjj6.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.amazonaws.com%2Fuploads%2Farticles%2F3u0wcbv3t46r62yufjj6.png" alt=" " width="800" height="662"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4eqjdl2d3vxqn9w4ynn.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.amazonaws.com%2Fuploads%2Farticles%2Fa4eqjdl2d3vxqn9w4ynn.png" alt=" " width="707" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;None of these numbers are what I'm most proud of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: AI that understands "how much RAM is Chrome eating"
&lt;/h2&gt;

&lt;p&gt;The most technically interesting part of PC Workman is hck_GPT — an AI assistant built directly into the app.&lt;/p&gt;

&lt;p&gt;No external API. Doesn't send your data anywhere. Works locally through a hybrid engine: if the intent gets recognized by the 82-intent parser, it responds deterministically from real data. If not, it delegates to a local Ollama LLM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user input
    → IntentParser (vocab match + ML classifier)
    → HybridEngine (rule dispatch vs LLM fallback)
    → ResponseBuilder (65 handlers, real sensor data)
    → bilingual response (PL/EN auto-detected)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;82 intents cover everything from "why is CPU high" to "can I run Cyberpunk" to "what's eating my battery." Each intent has dozens of patterns — because users ask the same thing 15 different ways.&lt;/p&gt;

&lt;p&gt;The bilingual helper looks almost embarrassingly simple:&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;_t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lang&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="n"&gt;pl&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="n"&gt;en&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="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;return&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Behind that sits 854 lines of vocabulary patterns in two languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: The Polish ł that broke routing
&lt;/h2&gt;

&lt;p&gt;This is one of my favorite bugs because it was so non-obvious.&lt;/p&gt;

&lt;p&gt;The parser normalizes text before matching — strips diacritics so "dlaczego" (why) with or without accents hits the same intent:&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;_ascii_fold&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;text&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="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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unicodedata&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;c&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="n"&gt;unicodedata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NFD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&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;unicodedata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;category&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="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mn&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;NFD normalization decomposes "ą" into "a" + combining ogonek, then the filter removes combining characters. Works great for ą, ę, ó, ź, ż, ń.&lt;/p&gt;

&lt;p&gt;But not for ł.&lt;/p&gt;

&lt;p&gt;ł (U+0142) isn't "l" with a combining stroke. It's a separate character that NFD doesn't decompose at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user types:    "jak dlugo wytrzyma bateria"   (plain l)
vocab pattern: "jak długo wytrzyma bateria"   (ł stays as ł after fold)

fold("długo") → "długo"   &amp;lt;- ł preserved
fold("dlugo") → "dlugo"   &amp;lt;- l preserved

"długo" ≠ "dlugo"  -&amp;gt; NO MATCH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flulfct91l5w4owounvje.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.amazonaws.com%2Fuploads%2Farticles%2Flulfct91l5w4owounvje.png" alt=" " width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The battery_estimate intent was returning conf=0.00 on a perfect question.&lt;/p&gt;

&lt;p&gt;Fix: explicit ASCII fallback patterns for every intent containing ł:&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;# vocabulary.py - battery_estimate patterns
&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jak dlugo wytrzyma bateria&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;# ASCII fallback
&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jak długo wytrzyma bateria&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;# canonical Polish
&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;how long will battery last&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;# English
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the type of bug you only find when building an app in two languages simultaneously and one of them has characters that don't behave the way you think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 3: 28 strangers designed 6 new features
&lt;/h2&gt;

&lt;p&gt;Few weeks ago I posted a simple question on GitHub Discussions and LinkedIn:&lt;/p&gt;

&lt;p&gt;"What would you ask an AI that lives inside your system monitor?"&lt;/p&gt;

&lt;p&gt;28 answers. From GitHub, LinkedIn DMs, comments.&lt;/p&gt;

&lt;p&gt;Every answer became a real function in the response builder.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Intent&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;game_can_run&lt;/td&gt;
&lt;td&gt;Checks if your PC can handle a game (20-game DB with RAM/VRAM/disk requirements)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;battery_estimate&lt;/td&gt;
&lt;td&gt;psutil.sensors_battery() + drain rate based on activity type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;upgrade_feasibility&lt;/td&gt;
&lt;td&gt;WMI slot count + current sticks + free slots&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;top_resource_hog&lt;/td&gt;
&lt;td&gt;TOP 5 processes by RSS memory + disk I/O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gaming_ram_usage&lt;/td&gt;
&lt;td&gt;Live game process RAM + 7-day comparison&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;daily_ram_usage&lt;/td&gt;
&lt;td&gt;7-day trend + verdict: very high / high / moderate / low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When you ask hck_GPT "can I run Cyberpunk" it checks your psutil RAM, WMI VRAM, free disk space and responds with specific numbers. No hallucination. No "usually..." No guessing.&lt;/p&gt;

&lt;p&gt;The no-data fallback is deliberate:&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;_no_data&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;intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;what_missing&lt;/span&gt;&lt;span class="o"&gt;=&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;lang&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&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;PREFIX&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; Not enough data for a reliable answer.&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;  I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;d rather tell you honestly than guess.&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;If I don't have data, I say so. AI that guesses is worse than AI that stays quiet.&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.amazonaws.com%2Fuploads%2Farticles%2F5tapihaxlygcvcs1k1pf.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.amazonaws.com%2Fuploads%2Farticles%2F5tapihaxlygcvcs1k1pf.png" alt=" " width="414" height="836"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 4: DeepMonitor - from ugly table to real tool
&lt;/h2&gt;

&lt;p&gt;For a long time the hardware view in PC Workman was weak. Inline min/max values with no alignment, dark uneven colors, no structure.&lt;/p&gt;

&lt;p&gt;Rewrote it from scratch on ttk.Treeview with 4 fixed columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;Sensor                    | Value     | Min       | Max
----------------------------------------------------------
&lt;/span&gt;  CPU
    [Temperatures]
      Package             | 52.1°C    | 44.0°C    | 52.1°C
      Core #0             | 49.3°C    | 45.1°C    | 51.8°C
    [Utilization]
      Processor           | 13.7%     |  0.0%     | 23.6%
    [Clocks]
      Current             | 3.990 GHz |           | 4.011 GHz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each category has its own background tint. Temperatures go from white to amber at 70°C to red at 83°C. Utilization hits red at 88%.&lt;/p&gt;

&lt;p&gt;Action bar: Save Data (exports .txt/.csv), Pause (freezes the view, button turns amber), Reset (clears session min/max).&lt;/p&gt;

&lt;p&gt;Same psutil and hardware_sensors feed hck_GPT. When DeepMonitor shows a red CPU temp line, the proactive monitor probably already sent an alert through hck_GPT a few minutes earlier. Two views, one data source.&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.amazonaws.com%2Fuploads%2Farticles%2F38rclec1na4nql3xlulq.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.amazonaws.com%2Fuploads%2Farticles%2F38rclec1na4nql3xlulq.png" alt=" " width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 5: Proactive monitor - AI that doesn't wait for your question
&lt;/h2&gt;

&lt;p&gt;One of my favorite modules. Runs in background and starts conversations on its own.&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;THROTTLE_RATIO&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.60&lt;/span&gt;   &lt;span class="c1"&gt;# below 60% of max freq = throttled
&lt;/span&gt;&lt;span class="n"&gt;CPU_SPIKE_PCT&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;30.0&lt;/span&gt;   &lt;span class="c1"&gt;# single process &amp;gt;30% = spike alert
&lt;/span&gt;&lt;span class="n"&gt;SESSION_BUDGET&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;      &lt;span class="c1"&gt;# max 3 unsolicited alerts per 30 min
&lt;/span&gt;&lt;span class="n"&gt;SESSION_WINDOW_S&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1800&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SESSION_BUDGET isn't random — based on CHI 2025 research on proactive AI assistants and when proactivity becomes annoying.&lt;/p&gt;

&lt;p&gt;Throttling alert:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hck_GPT: CPU power limit hit (58% of max). Heat is usually the cause. Type 'temperature'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GPU temperature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hck_GPT: GPU temperature spike to 89°C. Check cooling or lower graphics settings.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One alert. Specific reason. Specific next action. Not "your computer may be experiencing reduced performance."&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 6: Language sync — one hour debugging for one line
&lt;/h2&gt;

&lt;p&gt;For 10 months I built an app for Polish users entirely in English. That was a mistake I finally fixed.&lt;/p&gt;

&lt;p&gt;But the Settings language toggle didn't sync with hck_GPT. Click "PL" — interface changes, hck_GPT keeps responding in English.&lt;/p&gt;

&lt;p&gt;The fix was clean: utils/i18n.py has a callback system:&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;# panel.py __init__:
&lt;/span&gt;&lt;span class="nf"&gt;_i18n_register&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_i18n_lang_changed&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;_on_i18n_lang_changed&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;new_lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;_i18n_get_lang&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;_ui_lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_lang&lt;/span&gt;
    &lt;span class="n"&gt;proactive_monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_language&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_lang&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;parent&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;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;_refresh_welcome_for_lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After switching to PL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hck_GPT: Witaj z powrotem — PC Workman gotowy do działania.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One callback registration. One hour understanding why the widget wasn't refreshing at the right moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Numbers that surprised me
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;28,000 LinkedIn views on the "building what 28 people asked for" post&lt;/li&gt;
&lt;li&gt;27,500 views on "most developers never ship an .exe"&lt;/li&gt;
&lt;li&gt;1,135 em-dashes found and replaced in one maintenance session across 58 files&lt;/li&gt;
&lt;li&gt;241 processes in the knowledge base&lt;/li&gt;
&lt;li&gt;82 intents in the parser, each with dozens of PL+EN patterns&lt;/li&gt;
&lt;li&gt;0 external APIs — everything local
Most surprising: the two most viral posts weren't about the most technically interesting things. They were about truths every developer recognizes but rarely says out loud.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Security module — offline, no signatures, no cloud. Pattern detection on data PC Workman already collects.&lt;/p&gt;

&lt;p&gt;svch0st.exe pretending to be svchost.exe? Flagged.&lt;br&gt;
Crypto miner with abnormal CPU pattern 24/7? Flagged.&lt;br&gt;
New high-privilege process that wasn't there yesterday? Flagged.&lt;/p&gt;

&lt;p&gt;Your antivirus knows about threats from around the world. PC Workman knows what's normal for YOUR specific machine.&lt;/p&gt;

&lt;p&gt;And Microsoft Store submission. I've been saying this since v1.6.3. This time I mean it.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Current stats:&lt;/strong&gt; 56 GitHub stars, 270+ downloads, 270+ commits, 82 AI intents, 48,081 lines, 10 months, one €1.50 coffee donation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;github.com/HuckleR2003/PC_Workman_HCK&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;All links:&lt;/strong&gt; &lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;linktr.ee/marcin_firmuga&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have a question you'd ask an AI inside your system monitor — drop it in the comments. Every one becomes a real feature.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Marcin Firmuga | 22 | Poland | HCK_Labs&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Building PC Workman and GuideAI publicly. 10 months. 4 rebuilds. Still shipping.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About the Author
&lt;/h2&gt;

&lt;p&gt;I’m Marcin Firmuga. Solo developer and founder of HCK_Labs.&lt;/p&gt;

&lt;p&gt;I created PC Workman, an open-source, AI-powered PC resource monitor who learns, after time, your natural PC behavior (spikes, voltage, temps, usages) built entirely from scratch on dying hardware during warehouse shifts in the Netherlands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before this:&lt;/strong&gt; game translations, PC technician internships, warehouse operations in multiple countries, and countless failed projects I never finished.&lt;/p&gt;

&lt;p&gt;But this one? This one stuck.&lt;br&gt;
1000+ hours of code. 4 complete UI rebuilds. 16,000 lines deleted.&lt;br&gt;
3 AM all-nighters.Energy drinks and toast.&lt;/p&gt;

&lt;p&gt;And my own hck_GPT AI, building for months to give a PC Workman a brain and heart.&lt;br&gt;
And finally, an app I wouldn’t close in 5 seconds. That’s the difference between building and shipping.&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.amazonaws.com%2Fuploads%2Farticles%2Fz587dot6kwux3j5oveem.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz587dot6kwux3j5oveem.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PC_Workman is the result.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>How I Taught My Offline AI to Remember, Watch, and Warn, Without Any Cloud (Part 2)</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Tue, 12 May 2026 15:17:33 +0000</pubDate>
      <link>https://dev.to/huckler/how-i-taught-my-offline-ai-to-remember-watch-and-warn-without-any-cloud-part-2-5hib</link>
      <guid>https://dev.to/huckler/how-i-taught-my-offline-ai-to-remember-watch-and-warn-without-any-cloud-part-2-5hib</guid>
      <description>&lt;p&gt;Part 1 covered how hck_GPT routes messages through 9 layers and decides between rules and a local LLM. If you missed it:&lt;br&gt;
&lt;a href="https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523"&gt;Part 1 - Intent Scoring, Hybrid Routing, Temperature per Intent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That was the brain. This is the memory and the instincts.&lt;/p&gt;

&lt;p&gt;Part 1's AI was reactive. You ask, it answers. Close the app, everything is gone. No history. No learning. No initiative.&lt;/p&gt;

&lt;p&gt;That's not how a PC companion should work. If I've been running PC Workman for two weeks, it should know that my CPU averages 28% and today's 67% is unusual. It should notice that Chrome has been eating 2GB RAM for an hour and mention it before I ask. It should remember my GPU model without me telling it twice.&lt;/p&gt;

&lt;p&gt;So I built three systems that Part 1 didn't have: a persistent knowledge base that survives restarts, a metrics store that snapshots hardware data every 5 minutes into SQLite, and a proactive monitor that watches your system and pushes alerts without being asked.&lt;/p&gt;

&lt;p&gt;All offline. All local. Your data never leaves your machine.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. The Knowledge Base, AI That Remembers Across Restarts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Part 1 had session memory,&lt;/strong&gt;&lt;br&gt;
a Python dict that dies when the app closes. Useful for&lt;br&gt;
"we talked about RAM 3 messages ago" but useless for&lt;br&gt;
"your GPU is an RTX 3060 with 6GB VRAM"&lt;br&gt;
which shouldn't need re-scanning every launch.&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.amazonaws.com%2Fuploads%2Farticles%2Fon6z1mao8ansltjvmi6i.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.amazonaws.com%2Fuploads%2Farticles%2Fon6z1mao8ansltjvmi6i.png" alt=" " width="594" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Four tables, each with a different job:&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;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;EXISTS&lt;/span&gt; &lt;span class="nf"&gt;hardware_profile &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt;     &lt;span class="n"&gt;TEXT&lt;/span&gt; &lt;span class="n"&gt;PRIMARY&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt;   &lt;span class="n"&gt;TEXT&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated&lt;/span&gt; &lt;span class="n"&gt;REAL&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;EXISTS&lt;/span&gt; &lt;span class="nf"&gt;usage_patterns &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;metric&lt;/span&gt;  &lt;span class="n"&gt;TEXT&lt;/span&gt; &lt;span class="n"&gt;PRIMARY&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt;   &lt;span class="n"&gt;TEXT&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated&lt;/span&gt; &lt;span class="n"&gt;REAL&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;EXISTS&lt;/span&gt; &lt;span class="nf"&gt;user_facts &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt;        &lt;span class="n"&gt;TEXT&lt;/span&gt; &lt;span class="n"&gt;PRIMARY&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt;      &lt;span class="n"&gt;TEXT&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;source&lt;/span&gt;     &lt;span class="n"&gt;TEXT&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;DEFAULT&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;detected&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="n"&gt;REAL&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;DEFAULT&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;REAL&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;EXISTS&lt;/span&gt; &lt;span class="nf"&gt;conversation_log &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;         &lt;span class="n"&gt;INTEGER&lt;/span&gt; &lt;span class="n"&gt;PRIMARY&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;AUTOINCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;session_id&lt;/span&gt; &lt;span class="n"&gt;TEXT&lt;/span&gt;    &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt;  &lt;span class="n"&gt;REAL&lt;/span&gt;    &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;role&lt;/span&gt;       &lt;span class="n"&gt;TEXT&lt;/span&gt;    &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;    &lt;span class="n"&gt;TEXT&lt;/span&gt;    &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&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;hardware_profile&lt;/strong&gt; stores things that rarely change:&lt;br&gt;
CPU model, GPU name, VRAM, motherboard, RAM speed, OS version.&lt;/p&gt;

&lt;p&gt;Scanned once via psutil + WMI, then cached.&lt;br&gt;
The &lt;code&gt;hardware_is_fresh()&lt;/code&gt; method checks if the last scan was within 24 hours - if yes, skip the scan.&lt;br&gt;
No wasted resources on startup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;usage_patterns&lt;/strong&gt; stores things that change slowly:&lt;br&gt;
average CPU load, peak hours, top apps, detected use-case&lt;br&gt;
("gaming" vs "development" vs "office").&lt;br&gt;
Updated periodically from the stats engine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;user_facts&lt;/strong&gt; stores things the AI inferred or the user stated:&lt;br&gt;
preferred language, PC usage type, whether they play games.&lt;br&gt;
Each fact has a confidence score — detected facts start at 1.0, inferred facts can be lower.&lt;br&gt;
This is how hck_GPT knows to greet you in Polish without asking every session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;conversation_log&lt;/strong&gt; keeps the last 500 messages across sessions&lt;br&gt;
(pruned monthly). Not for replaying conversations, for pattern detection. "User asks about temperature every Monday" is a signal.&lt;/p&gt;

&lt;p&gt;The knowledge base builds a context summary for every AI response:&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;build_knowledge_summary&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;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;hw&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;get_all_hardware&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;facts&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;get_all_facts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&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;hw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hardware:&lt;/span&gt;&lt;span class="sh"&gt;"&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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_HW_LABELS&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;in&lt;/span&gt; &lt;span class="n"&gt;hw&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;hw&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="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&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;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hw&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="si"&gt;}&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;facts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User facts:&lt;/span&gt;&lt;span class="sh"&gt;"&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;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;facts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;())[:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lines&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;lines&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(knowledge base empty)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gets injected into every Ollama prompt. The LLM doesn't ask "what GPU do you have?", it already knows.&lt;br&gt;
From the first message of every session.&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.amazonaws.com%2Fuploads%2Farticles%2F6rldniwf64djsajtylxn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rldniwf64djsajtylxn.gif" alt=" " width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Metrics Store, 90 Days of Hardware History in SQLite
&lt;/h2&gt;

&lt;p&gt;Session memory remembers what happened in the last 30 minutes.&lt;br&gt;
The knowledge base remembers your hardware profile.&lt;br&gt;
But what about "was my CPU hotter yesterday than today?"&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.amazonaws.com%2Fuploads%2Farticles%2Flunbge1svzvs8q73jxg2.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.amazonaws.com%2Fuploads%2Farticles%2Flunbge1svzvs8q73jxg2.png" alt=" " width="799" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Metrics Store answers that. Every 5 minutes, a background thread snapshots 20+ sensor values into SQLite:&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;SNAPSHOT_INTERVAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;   &lt;span class="c1"&gt;# 5 minutes between snapshots
&lt;/span&gt;&lt;span class="n"&gt;RETENTION_DAYS&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;    &lt;span class="c1"&gt;# auto-prune after 90 days
&lt;/span&gt;
&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;EXISTS&lt;/span&gt; &lt;span class="nf"&gt;deepmonitor_snapshots &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;            &lt;span class="n"&gt;INTEGER&lt;/span&gt; &lt;span class="n"&gt;PRIMARY&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;AUTOINCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ts&lt;/span&gt;            &lt;span class="n"&gt;REAL&lt;/span&gt;    &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;date_str&lt;/span&gt;      &lt;span class="n"&gt;TEXT&lt;/span&gt;    &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cpu_load&lt;/span&gt;      &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cpu_temp&lt;/span&gt;      &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cpu_mhz&lt;/span&gt;       &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cpu_power&lt;/span&gt;     &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;gpu_temp&lt;/span&gt;      &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;gpu_load&lt;/span&gt;      &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;gpu_vram_pct&lt;/span&gt;  &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;gpu_power&lt;/span&gt;     &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ram_pct&lt;/span&gt;       &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;swap_pct&lt;/span&gt;      &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mb_temp_sys&lt;/span&gt;   &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mb_volt_12v&lt;/span&gt;   &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mb_volt_5v&lt;/span&gt;    &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mb_volt_33v&lt;/span&gt;   &lt;span class="n"&gt;REAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;disk_json&lt;/span&gt;     &lt;span class="n"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This table shares the same &lt;code&gt;hck_stats.db&lt;/code&gt; file as the main stats engine — one database, WAL mode, concurrent reads and writes without locks.&lt;/p&gt;

&lt;p&gt;The writer loop staggers its first write by 60 seconds so the UI finishes loading first:&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;_writer_loop&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="bp"&gt;None&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;_stop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# let UI boot
&lt;/span&gt;    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&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;_stop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_set&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;try&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;_save_snapshot&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;_prune_old_rows&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;writer error: %s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&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;_stop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SNAPSHOT_INTERVAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auto-prune runs after every snapshot — rows older than 90 days get deleted. Database stays small (~5-10 MB per month).&lt;/p&gt;

&lt;p&gt;The critical part is what happens on startup:&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;_load_historical_baselines&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="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;since&lt;/span&gt; &lt;span class="o"&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;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;86400&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        SELECT
          AVG(CASE WHEN cpu_load &amp;gt;= 0 THEN cpu_load END) AS cpu_av,
          AVG(CASE WHEN ram_pct  &amp;gt;= 0 THEN ram_pct  END) AS ram_av,
          MIN(CASE WHEN cpu_load &amp;gt;= 0 THEN cpu_load END) AS cpu_lo,
          MAX(CASE WHEN cpu_load &amp;gt;= 0 THEN cpu_load END) AS cpu_hi,
          COUNT(*) AS n
        FROM deepmonitor_snapshots WHERE ts &amp;gt;= ?
    &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;span class="n"&gt;since&lt;/span&gt;&lt;span class="p"&gt;,)).&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;live_sensors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_hist_cpu_avg_7d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu_av&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_hist_ram_avg_7d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ram_av&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&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;On app boot, the store loads 7-day min/max/avg baselines into live memory. From the very first message, hck_GPT can say "your CPU is at 67% — but your 7-day average is 28%, something is off." Not because it guessed. Because it has 2,016 data points from the last week (288 snapshots/day × 7 days).&lt;/p&gt;

&lt;p&gt;Without this, the AI would need to run for hours before it could make any comparison. With it, historical context is available from second one.&lt;/p&gt;

&lt;p&gt;The public API is simple — two methods cover 90% of use cases:&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;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metrics_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_history&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# raw snapshots
&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metrics_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;daily_summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# per-day aggregates
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. The Proactive Monitor, AI That Speaks First
&lt;/h2&gt;

&lt;p&gt;This is the part that makes people say "wait, it does WHAT?"&lt;/p&gt;

&lt;p&gt;Most AI assistants wait for input. You type, they respond. Passive.&lt;/p&gt;

&lt;p&gt;hck_GPT's Proactive Monitor is a daemon thread that runs every 45 seconds, checks system state, and pushes alerts to the chat panel without anyone asking.&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;CPU_HIGH_PCT&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;85.0&lt;/span&gt;
&lt;span class="n"&gt;CPU_CRIT_PCT&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;95.0&lt;/span&gt;
&lt;span class="n"&gt;RAM_HIGH_PCT&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;88.0&lt;/span&gt;
&lt;span class="n"&gt;RAM_CRIT_PCT&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;93.0&lt;/span&gt;
&lt;span class="n"&gt;DISK_LOW_GB&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;
&lt;span class="n"&gt;THROTTLE_RATIO&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.60&lt;/span&gt;
&lt;span class="n"&gt;CHECK_INTERVAL_S&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;
&lt;span class="n"&gt;MIN_GAP_SAME_S&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;   &lt;span class="c1"&gt;# don't repeat same alert for 5 min
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seven conditions monitored:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CPU sustained high&lt;/strong&gt;, not a spike, sustained.&lt;br&gt;
Two consecutive checks above 85% before alerting.&lt;br&gt;
One check could be a game loading.&lt;br&gt;
Two means something is wrong.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CPU critical&lt;/strong&gt; - above 95%. Immediate alert.&lt;br&gt;
No waiting for second check.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RAM high&lt;/strong&gt; - above 88%. Suggests checking what's eating memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RAM critical&lt;/strong&gt; - above 93%. Pagefile is getting hit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CPU throttling&lt;/strong&gt; - current frequency divided by max frequency below 60%. Your CPU is being thermally limited.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Disk nearly full&lt;/strong&gt; - any partition below 4 GB free.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Long session&lt;/strong&gt; - PC running for many hours. Gentle reminder.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every alert has a bilingual message pool, Polish and English versions with slight variations so the same alert doesn't read identically twice:&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;_MSGS&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;cpu_high&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hck_GPT: ⚠ CPU sustained at {val}%. Type &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;top processes&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; to see who&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s responsible.&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;hck_GPT: CPU {val}% — something&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s eating it. Type &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;top&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; to find out what.&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;hck_GPT: Heads up — CPU at {val}%. Expected, or something sneaky in the background?&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pl&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hck_GPT: ⚠ CPU na {val}% od dłuższego czasu. Wpisz &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;top procesy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; żeby zobaczyć winowajcę.&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;hck_GPT: CPU {val}% — coś go zjada. Jeśli to nie Ty, to kto? Wpisz &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;top&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&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;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 anti-spam logic is critical. Without it, a sustained CPU spike would flood the chat with warnings every 45 seconds:&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;MIN_GAP_SAME_S&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;  &lt;span class="c1"&gt;# 5 minutes between same alert type
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_should_push&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&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;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;last&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;_last_push&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="n"&gt;key&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;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;MIN_GAP_SAME_S&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&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;_last_push&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;
    &lt;span class="k"&gt;return&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 push mechanism uses callbacks — the UI registers a function, the monitor calls it from the background thread:&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;proactive_monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;root&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;0&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;panel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&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;code&gt;root.after(0, ...)&lt;/code&gt; schedules the message on tkinter's main thread. Background thread never touches the GUI directly. No race conditions. No crashes.&lt;/p&gt;

&lt;p&gt;There's also a silent banner callback for non-intrusive status updates — "All quiet" vs "CPU 87% SPIKE | 2 alerts" in the hck_GPT status bar.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Bilingual Vocabulary — 854 Lines, Zero Translation API
&lt;/h2&gt;

&lt;p&gt;Part 1 mentioned that Polish and English patterns are "defined separately." Here's what that actually looks like at scale.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vocabulary.py&lt;/code&gt; is 854 lines. 25+ intents. Each intent has a list of trigger patterns in both languages, mixed together:&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;INTENT_PATTERNS&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;hw_cpu&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;span class="c1"&gt;# Polish tokens
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;procesor&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;rdzeń&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;rdzenie&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;taktowanie&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;# English tokens
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu&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;processor&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;cores&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;boost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;# Polish multi-word (high bonus)
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jaki procesor&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;jaki mam procesor&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;ile rdzeni&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;co mam za procesor&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;powiedz mi o procesorze&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;# English multi-word
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;what cpu&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;my cpu&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;which processor&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;tell me about my cpu&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;cpu details&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No translation step.&lt;br&gt;
No language detection preprocessing.&lt;br&gt;
Both languages live in the same list.&lt;br&gt;
The intent parser scores them all the same way — exact match, prefix match, typo tolerance. If someone types "jaki mam procesor" they get the same intent (&lt;code&gt;hw_cpu&lt;/code&gt;) with the same confidence as "what cpu do I have."&lt;/p&gt;

&lt;p&gt;The scoring comment at the top of the file explains the math:&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;# Pattern scoring (in parser.py):
#   - Multi-word phrases:  len(words) * 1.5  (biggest bonus)
#   - Exact single token:  1.0
#   - Partial prefix:      0.4
#   - Normalised:          min(1.0, score / 3.0)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding more multi-word phrases to an intent raises its confidence, making it more likely to hit the 0.60 threshold for the rule engine.&lt;br&gt;
Ambiguous queries stay below threshold and go to Ollama.&lt;br&gt;
The vocabulary file IS the tuning knob, no hyperparameters to optimize, just patterns to add.&lt;/p&gt;

&lt;p&gt;This week I added 12 new intents based on questions from LinkedIn followers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;battery_drain&lt;/code&gt; - "Which process is draining my battery?"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;session_compare&lt;/code&gt; - "Was it better yesterday?"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pc_changes&lt;/code&gt; - "What changed since yesterday?"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;startup_safety&lt;/code&gt; - "Is it safe to disable this?"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;browser_cache&lt;/code&gt; - "Is my browser slow because of caching?"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;swap_analysis&lt;/code&gt; - "Which processes are using swap?"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;network_usage&lt;/code&gt; - "Which process is using my network?"
Each one: 10-20 patterns, Polish + English, with bilingual response handlers reading live data from psutil and the metrics store.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Part 1 + Part 2 Give You Together
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Part 1&lt;/th&gt;
&lt;th&gt;Part 2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Input processing&lt;/td&gt;
&lt;td&gt;Intent parser, confidence scoring&lt;/td&gt;
&lt;td&gt;Bilingual vocabulary (854 lines)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decision&lt;/td&gt;
&lt;td&gt;9-layer routing, hybrid engine&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response&lt;/td&gt;
&lt;td&gt;Rule engine + Ollama, temperature per intent&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Short-term memory&lt;/td&gt;
&lt;td&gt;Session dict, trend tracking&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-term memory&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;User Knowledge Base (SQLite, AppData)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Historical data&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Metrics Store (snapshots q5min, 90-day retention)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proactive behavior&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Daemon monitor (7 conditions, anti-spam, bilingual alerts)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Startup context&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;7-day baselines loaded on boot&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Part 1 built a brain that responds. Part 2 gave it memory that persists, data that accumulates, and instincts that act without being asked.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Still Missing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cross-session conversation context.&lt;/strong&gt;&lt;br&gt;
The knowledge base stores hardware profiles and usage patterns, but conversation topics don't persist. If you asked about RAM yesterday, today's session doesn't know.&lt;br&gt;
The conversation_log table has the data — the response builder just doesn't query it yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Predictive alerts.&lt;/strong&gt; The proactive monitor reacts to current state.&lt;br&gt;
It doesn't predict. "Your RAM tends to spike around 9 PM on weekdays" is possible with the metrics store data - the SQL is straightforward, the pattern detection isn't built yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automatic vocabulary expansion.&lt;/strong&gt; Every unrecognized query requires manual pattern addition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A feedback loop that logs low-confidence queries and suggests new patterns would cut maintenance time significantly.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Offline-First Philosophy
&lt;/h2&gt;

&lt;p&gt;Every feature in this article stores data locally. SQLite in AppData. Snapshots in the shared stats database.&lt;br&gt;
Alerts computed from psutil readings. Nothing is sent anywhere.&lt;/p&gt;

&lt;p&gt;**This isn't a limitation - it's a design choice.&lt;br&gt;
**When your app monitors CPU temperatures, reads Windows registry, scans running processes, and tracks usage patterns over 90 days, the data is sensitive by definition.&lt;br&gt;
Sending it to a cloud API for every interaction isn't just slow. It's a trust problem.&lt;/p&gt;

&lt;p&gt;The optional Ollama integration (coming before v2.0) will give users a choice: stay fully offline with the Core AI, or enable a local LLM for smarter conversations.&lt;br&gt;
The key word is "local." Even the LLM runs on your hardware.&lt;/p&gt;

&lt;p&gt;Your data. Your machine. Your choice.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Project
&lt;/h2&gt;

&lt;p&gt;PC Workman is open source. MIT licensed.&lt;br&gt;
&lt;strong&gt;The .exe doesn't require Python.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Download: &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;&lt;br&gt;
Part 1: &lt;a href="https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523"&gt;How I Built an Offline AI Assistant in Python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All my links: &lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;linktr.ee/marcin_firmuga&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Currently doing Google's AI certification (Umiejętności Jutra 3.0 through SGH).&lt;br&gt;
Curious how it'll change the way I think about this engine.&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.amazonaws.com%2Fuploads%2Farticles%2F6im1p54s0eckow9ev075.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6im1p54s0eckow9ev075.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Marcin Firmuga | Python Developer | HCK_Labs&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Building PC Workman publicly between retail shifts. 800+ hours, 28 GitHub stars, and an AI that now remembers what it told you last week.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Real guide from my 10 months of work PC Workman
(Open Source, fully build in public (fails, tiny wins)</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Mon, 04 May 2026 06:44:25 +0000</pubDate>
      <link>https://dev.to/huckler/real-guide-from-my-10-months-of-work-pc-workman-open-source-fully-build-in-public-fails-tiny-6k1</link>
      <guid>https://dev.to/huckler/real-guide-from-my-10-months-of-work-pc-workman-open-source-fully-build-in-public-fails-tiny-6k1</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523" class="crayons-story__hidden-navigation-link"&gt;How I Built an Offline AI Assistant in Python - No OpenAI, No LangChain, No Dependencies&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
      &lt;a href="https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523" class="crayons-article__context-note crayons-article__context-note__feed"&gt;&lt;p&gt;A 5-step decision chain for two languages&lt;/p&gt;

&lt;/a&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/huckler" class="crayons-avatar  crayons-avatar--l  "&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3693207%2F6a4682e6-273e-4a98-9ce7-653391a5abcc.png" alt="huckler profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/huckler" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Marcin Firmuga
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Marcin Firmuga
                
              
              &lt;div id="story-author-preview-content-3604170" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/huckler" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3693207%2F6a4682e6-273e-4a98-9ce7-653391a5abcc.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Marcin Firmuga&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 3&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523" id="article-link-3604170"&gt;
          How I Built an Offline AI Assistant in Python - No OpenAI, No LangChain, No Dependencies
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;62&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              4&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            9 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>How I Built an Offline AI Assistant in Python - No OpenAI, No LangChain, No Dependencies</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Sun, 03 May 2026 13:45:33 +0000</pubDate>
      <link>https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523</link>
      <guid>https://dev.to/huckler/how-i-built-an-offline-ai-assistant-in-python-no-openai-no-langchain-no-dependencies-4523</guid>
      <description>&lt;p&gt;Every tutorial about building an AI assistant starts the same way:&lt;br&gt;
&lt;code&gt;pip install openai&lt;/code&gt;. Get an API key. Send everything to GPT. Done.&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.amazonaws.com%2Fuploads%2Farticles%2Fzhygehs3k9e4wkcyz279.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.amazonaws.com%2Fuploads%2Farticles%2Fzhygehs3k9e4wkcyz279.png" alt=" " width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now your assistant costs money per message, dies without internet, and you have zero control over what happens between the question and the answer.&lt;/p&gt;

&lt;p&gt;I needed something different.&lt;/p&gt;

&lt;p&gt;PC Workman is an open-source system monitor that runs on people's PCs. Some of those PCs are behind firewalls.&lt;br&gt;
Some users don't want their system data leaving their machine.&lt;/p&gt;

&lt;p&gt;So I built hck_GPT... a hybrid AI assistant that works fully offline,&lt;br&gt;
handles Polish and English without a language model, routes messages through a 5-step decision chain, blends keyword scoring with&lt;br&gt;
ML confidence, remembers what it said 3 messages ago, and optionally talks to a local LLM (Ollama) when it's available.&lt;/p&gt;

&lt;p&gt;No cloud. No API key. No &lt;code&gt;pip install&lt;/code&gt; magic.&lt;br&gt;
Here's how it works. All of it.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. Intent Scoring - One Algorithm for Two Languages, Zero NLP Libraries
&lt;/h2&gt;

&lt;p&gt;The first problem: how do you figure out what someone is asking without shipping a 500MB NLP model?&lt;/p&gt;

&lt;p&gt;Most intent parsers use spaCy, NLTK, or a transformer. I used string matching. But not the dumb kind.&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;_score_intent&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;tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&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="n"&gt;full_text&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="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Multi-word phrase -&amp;gt; bonus proportional to word count
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;full_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;score&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;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;   &lt;span class="c1"&gt;# "why is ram so high" = 5 x 1.5
&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;if&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;                          &lt;span class="c1"&gt;# exact match
&lt;/span&gt;            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&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;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&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;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="ow"&gt;and&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;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
            &lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt;                          &lt;span class="c1"&gt;# prefix match ("perfor" -&amp;gt; "performance")
&lt;/span&gt;            &lt;span class="k"&gt;elif&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;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;any&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;_edit_distance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&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;t&lt;/span&gt;&lt;span class="p"&gt;)&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;pattern&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="ow"&gt;and&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;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
            &lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;                          &lt;span class="c1"&gt;# typo tolerance: 1-char edit distance
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three levels of matching in a single loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exact match&lt;/strong&gt; gives 1.0 - "cpu" in tokens, done.&lt;br&gt;
&lt;strong&gt;Prefix match&lt;/strong&gt; gives 0.4 - "perfor" matches "performance".&lt;br&gt;
This is how the parser handles both languages without a language detector.&lt;br&gt;
Polish and English vocabulary patterns are defined separately, but the scoring algorithm is identical.&lt;br&gt;
&lt;strong&gt;Typo tolerance&lt;/strong&gt; gives 0.6 - Levenshtein distance of 1 catches "temperture" → "temperature" without a spell checker.&lt;/p&gt;

&lt;p&gt;Multi-word phrases get bonus scoring proportional to word count. "what changed in performance" (5 words x 1.5 = 7.5 pts) beats a standalone "performance" (1 pt).&lt;br&gt;
More specific queries earn higher confidence.&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.amazonaws.com%2Fuploads%2Farticles%2F9fxmgk7ro83i18yglobk.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.amazonaws.com%2Fuploads%2Farticles%2F9fxmgk7ro83i18yglobk.png" alt=" " width="800" height="871"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The edit distance function has an early-exit: if the length difference between two strings is more than 2, skip the computation entirely.&lt;br&gt;
This matters because this runs on every message in a GUI thread.&lt;br&gt;
Blocking for 200ms on a distance calculation would feel like lag.&lt;/p&gt;

&lt;p&gt;Zero dependencies. Works in both languages. Runs in under 1ms.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Hybrid Confidence - When to Trust ML, When to Trust Keywords
&lt;/h2&gt;

&lt;p&gt;If you have a keyword scorer AND an ML classifier, you need to decide who wins. Most systems pick one. I blend them.&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;_blend_with_ml&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;text&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="n"&gt;kw_intent&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="n"&gt;kw_conf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ml_intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ml_conf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ml_classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&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;ml_conf&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# ML very confident — trust it outright
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ml_intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ml_conf&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ml_conf&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.35&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;ml_intent&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;kw_intent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Agreement -&amp;gt; amplify the signal
&lt;/span&gt;            &lt;span class="n"&gt;blended&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.65&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ml_conf&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.35&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;kw_conf&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ml_intent&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="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blended&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="c1"&gt;# Disagreement → pick the stronger weighted signal
&lt;/span&gt;            &lt;span class="n"&gt;ml_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.65&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ml_conf&lt;/span&gt;
            &lt;span class="n"&gt;kw_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.35&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;kw_conf&lt;/span&gt;
            &lt;span class="n"&gt;winner&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ml_intent&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ml_score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;kw_score&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;kw_intent&lt;/span&gt;
            &lt;span class="n"&gt;conf&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&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;ml_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kw_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.15&lt;/span&gt; &lt;span class="o"&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;ml_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kw_score&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;winner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;

    &lt;span class="c1"&gt;# ML not confident enough - fall back to pure keyword scoring
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;kw_intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kw_conf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three trust zones instead of one threshold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Above 0.70&lt;/strong&gt; - ML is confident. Trust it. Keywords don't get a vote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Between 0.35 and 0.69&lt;/strong&gt;, the interesting zone. If both models agree on the intent, the blended confidence goes up (agreement, amplified signal). If they disagree, the loser still gets 15% of the vote.&lt;br&gt;
That 15% matters it prevents the winner from being overconfident on ambiguous inputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Below 0.35&lt;/strong&gt; - ML doesn't know. Pure keyword scoring takes over.&lt;/p&gt;

&lt;p&gt;The 0.65/0.35 weight split is intentional.&lt;br&gt;
ML gets more weight because when it's right, it understands full semantics. Keywords only match surface patterns.&lt;br&gt;
But keywords are more reliable on short, domain-specific inputs like&lt;br&gt;
"cpu" or "mb" where ML tends to underperform.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. The Routing Decision - 5 Steps from Message to Answer
&lt;/h2&gt;

&lt;p&gt;This is the core of the whole engine. Every message follows the same path:&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;RULE_THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.60&lt;/span&gt;   &lt;span class="c1"&gt;# above -&amp;gt; deterministic rule engine
&lt;/span&gt;&lt;span class="n"&gt;LOW_THRESHOLD&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.20&lt;/span&gt;   &lt;span class="c1"&gt;# below -&amp;gt; not worth even trying
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process&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;msg&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="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ParseResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;confidence&lt;/span&gt;
    &lt;span class="n"&gt;intent&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 1: Open-ended queries -&amp;gt; LLM first
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;small_talk&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;unknown&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_check_available&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="nf"&gt;_query_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&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;response_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# graceful degradation
&lt;/span&gt;
    &lt;span class="c1"&gt;# Step 2: High confidence -&amp;gt; deterministic, instant answer
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;RULE_THRESHOLD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&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;resp&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;resp&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 3: Medium confidence -&amp;gt; try LLM for smarter answer
&lt;/span&gt;    &lt;span class="k"&gt;if&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;_check_available&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;llm_resp&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;_query_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&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;llm_resp&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;llm_resp&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 4: LLM unavailable → rule engine best-effort
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;LOW_THRESHOLD&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;response_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 5: Nothing works → caller handles it
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No single point of failure. Every step has a fallback.&lt;/p&gt;

&lt;p&gt;Type "cpu" → keyword confidence is 0.95 → Step 2 handles it instantly. Rule engine. Deterministic. No LLM involved.&lt;/p&gt;

&lt;p&gt;Type "why is my computer acting weird today" → keyword confidence is 0.30 → Step 2 skips → Step 3 sends it to Ollama with full system context → if Ollama is down, Step 4 gives a best-effort rule response.&lt;/p&gt;

&lt;p&gt;Type "how are you" → intent is "small_talk" → Step 1 sends it straight to LLM → if unavailable, rule engine returns a canned friendly response.&lt;/p&gt;

&lt;p&gt;I didn't want Ollama for everything, it's slow (2-5 seconds).&lt;br&gt;
I didn't want if/else for everything, it can't handle questions&lt;br&gt;
I didn't anticipate.&lt;br&gt;
So I gave every message a confidence score and&lt;br&gt;
let the score decide which engine handles it.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. Intent-Aware Temperature - The Surgeon vs The Friend
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytgdjpbcczx8fr5i9omq.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.amazonaws.com%2Fuploads%2Farticles%2Fytgdjpbcczx8fr5i9omq.png" alt=" " width="612" height="750"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every AI tutorial I've seen uses one temperature setting. Global. Static.&lt;br&gt;
Same creativity level whether you're asking about CPU specs or saying hello.&lt;/p&gt;

&lt;p&gt;I use 20 different temperatures.&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;_INTENT_TEMPERATURE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&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="nb"&gt;float&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="c1"&gt;# Factual / diagnostic - precision over creativity
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hw_cpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# wrong MHz is bad advice
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hw_gpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;throttle_check&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stats&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;          &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;disk_health&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ram_why_high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mf"&gt;0.40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;why_slow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="mf"&gt;0.45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;# Optimization - some creativity welcome
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;performance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="mf"&gt;0.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;optimization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mf"&gt;0.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;speed_up_pc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="mf"&gt;0.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;health_check&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mf"&gt;0.50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;# Conversational - warmth and personality
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;small_talk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="mf"&gt;0.80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# "how are you" deserves a human answer
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;about_program&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;help&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;           &lt;span class="mf"&gt;0.60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_INTENT_TEMPERATURE&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="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TEMPERATURE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# default 0.72
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"What CPU do I have?" -&amp;gt; 0.35. I want a surgeon.&lt;br&gt;
The answer is a fact: Intel Core i7-12700H, 14 cores, 4.7 GHz boost.&lt;br&gt;
There is exactly one correct answer.&lt;br&gt;
Creativity here means wrong numbers.&lt;/p&gt;

&lt;p&gt;"How are you?" -&amp;gt; 0.80. I want a friend.&lt;br&gt;
Warmth, personality, maybe a joke.&lt;/p&gt;

&lt;p&gt;"Why is my PC slow?" -&amp;gt; 0.45. Somewhere between.&lt;br&gt;
The diagnostic needs to be accurate, but the explanation should be readable, not a data dump.&lt;/p&gt;

&lt;p&gt;One line of code.&lt;br&gt;
Massive difference in response quality.&lt;br&gt;
Probably the highest value-per-line-of-code in the entire engine.&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Fallback Chain with Availability Cache
&lt;/h2&gt;

&lt;p&gt;Ollama runs locally but it's not always there.&lt;br&gt;
&lt;strong&gt;Maybe **the user didn't install it.&lt;br&gt;
**Maybe **the model is loading. Maybe it crashed.&lt;br&gt;
**Your assistant can't hang for 30 seconds waiting to find out.&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;AVAILABILITY_TTL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;   &lt;span class="c1"&gt;# re-check Ollama every 5 minutes
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_check_available&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;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&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;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Respect the cool-down from previous failures
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;_temp_unavail_until&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="c1"&gt;# Cache: don't ping /api/tags on every message
&lt;/span&gt;    &lt;span class="k"&gt;if&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;_available&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&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;_available_checked_at&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;AVAILABILITY_TTL&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;_available&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;_ollama&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_available&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;_available_checked_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;
        &lt;span class="k"&gt;if&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;_available&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;_pick_best_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;# llama3.2 &amp;gt; mistral &amp;gt; phi3 &amp;gt; gemma &amp;gt; first available
&lt;/span&gt;
    &lt;span class="k"&gt;return&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_available&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;_query_llm&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;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;raw&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;_ollama&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&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;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt;
    &lt;span class="k"&gt;except&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_temp_unavail_until&lt;/span&gt; &lt;span class="o"&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;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;   &lt;span class="c1"&gt;# crash -&amp;gt; 60s cool-down
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&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;raw&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;_temp_unavail_until&lt;/span&gt; &lt;span class="o"&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;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;   &lt;span class="c1"&gt;# empty -&amp;gt; model loading, 30s
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&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="nf"&gt;_format_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two levels of cool-down. Empty response (model loading) -&amp;gt;** 30 seconds*&lt;em&gt;. Exception (crash, timeout) -&amp;gt;&lt;/em&gt;* 60 seconds*&lt;em&gt;.&lt;br&gt;
Full availability re-check -&amp;gt; **every 5 minutes&lt;/em&gt;*.&lt;/p&gt;

&lt;p&gt;The user never waits for a ping. If Ollama was unavailable 10 seconds ago, the engine routes to rules immediately.&lt;br&gt;
Answer in milliseconds instead of a spinner.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_pick_best_model()&lt;/code&gt; runs once on availability check:&lt;br&gt;
llama3.2 &amp;gt; mistral &amp;gt; phi3 &amp;gt; gemma &amp;gt; whatever is installed.&lt;br&gt;
If you have multiple models, hck_GPT picks the best one automatically.&lt;/p&gt;


&lt;h2&gt;
  
  
  6. Session Memory - AI That Remembers What It Said 3 Messages Ago
&lt;/h2&gt;

&lt;p&gt;Most chatbot tutorials treat every message as independent.&lt;br&gt;
User asks about RAM. Gets an answer.&lt;br&gt;
User asks about system health. Gets a generic response that doesn't mention the RAM issue from 30 seconds ago.&lt;br&gt;
hck_GPT remembers.&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;# When answering a RAM question - save the data:
&lt;/span&gt;&lt;span class="n"&gt;session_memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record_response_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hw_ram&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total_gb&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;speed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="mi"&gt;3200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current_pct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;typical_avg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Later, in a different handler (health_check) - reference it:
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_resp_health_check&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;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ram_sess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session_memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_response_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hw_ram&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;ram_sess&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;total_gb&lt;/span&gt;&lt;span class="sh"&gt;"&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;ram&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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;  (Your &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ram_sess&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;total_gb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; GB RAM we discussed earlier&lt;/span&gt;&lt;span class="sh"&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; - now at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ram&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%, that&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s worth watching)&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;No SQLite. No JSON file. Just a dict:&lt;br&gt;
&lt;code&gt;{intent: {key: val, recorded_at: timestamp}}&lt;/code&gt;.&lt;br&gt;
Lives in RAM for the session. When the app closes, it's gone.&lt;br&gt;
That's intentional, session memory shouldn't outlive the session.&lt;/p&gt;

&lt;p&gt;There's also trend tracking fed by snapshots every 30 seconds:&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;get_trend&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;metric&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;buf&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;_cpu_trend&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;else&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;_ram_trend&lt;/span&gt;
    &lt;span class="n"&gt;readings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# circular buffer of last 8 readings
&lt;/span&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;readings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;mid&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;readings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;first_avg&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;readings&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt;
    &lt;span class="n"&gt;second_avg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;readings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&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="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;readings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;delta&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;second_avg&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;first_avg&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rising&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;delta&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;falling&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Split the buffer in half. Compare averages. Rising, falling, or stable. This lets hck_GPT say "your CPU has been climbing for the last few minutes" instead of just showing the current number.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. System Prompt with Live PC Context — Facts, Not Vibes
&lt;/h2&gt;

&lt;p&gt;When a message reaches Ollama, the LLM doesn't guess about your system.&lt;br&gt;
It gets injected context built from real data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;== Live System State ==
CPU: 67%  @ 3840 MHz / max 4800 MHz
RAM: 71%  (11.4/16.0 GB used,  4.6 GB free)
Disk C: 48.3 GB free / 476.0 GB total

== Today's Averages ==
CPU avg: 34.2%  peak: 89.0%
RAM avg: 68.1%

== Top Processes (by CPU) ==
  chrome.exe       CPU 18.4%  RAM 892 MB
  code.exe         CPU 12.1%  RAM 441 MB
  python.exe       CPU  3.2%  RAM 156 MB

== Hardware Profile ==
CPU: Intel Core i7-12700H  (14 cores, boost 4.7 GHz)
GPU: NVIDIA GeForce RTX 3060  VRAM: 6 GB
RAM: 16.0 GB @ 3200 MHz

== Today vs Typical ==
CPU today 34% vs typical 28%  /\ (+6%)
RAM today 71% vs typical 51%  /\ (+20%)

== Learned Usage Patterns ==
Typical CPU avg (7-day baseline): 28%
Heaviest app this week: chrome.exe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each section comes from a different module. psutil for live data.&lt;br&gt;
SQLite for historical averages. WMI for hardware profile.&lt;br&gt;
The Stats Engine for 7-day baselines.&lt;/p&gt;

&lt;p&gt;The "Today vs Typical" section is the difference between an assistant that says "CPU 67%" and one that says "CPU 67% — but your normal is 28%, something is off." Context, not just data. That's the whole philosophy in two lines of a prompt.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Costs vs The OpenAI Approach
&lt;/h2&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;hck_GPT (this approach)&lt;/th&gt;
&lt;th&gt;pip install openai&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dependencies&lt;/td&gt;
&lt;td&gt;zero (beyond psutil)&lt;/td&gt;
&lt;td&gt;openai, tiktoken, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model size&lt;/td&gt;
&lt;td&gt;zero (rule engine is pure Python)&lt;/td&gt;
&lt;td&gt;N/A (cloud)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API costs&lt;/td&gt;
&lt;td&gt;zero&lt;/td&gt;
&lt;td&gt;$0.002-0.06 per message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;&amp;lt;1ms rules, 2-5s Ollama&lt;/td&gt;
&lt;td&gt;500-2000ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internet&lt;/td&gt;
&lt;td&gt;not required&lt;/td&gt;
&lt;td&gt;required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privacy&lt;/td&gt;
&lt;td&gt;data stays local&lt;/td&gt;
&lt;td&gt;sent to OpenAI servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAM&lt;/td&gt;
&lt;td&gt;~5MB&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;The intent vocabulary is hand-built.&lt;br&gt;
~200 patterns across 25 intents.&lt;br&gt;
Every time a user asks something I didn't anticipate,&lt;br&gt;
I add patterns manually. This doesn't scale past maybe 50 intents.&lt;br&gt;
A lightweight local classifier (even scikit-learn with TF-IDF) would handle the long tail better.&lt;/p&gt;

&lt;p&gt;The confidence thresholds (0.60, 0.35, 0.20) were tuned by testing, not by math. They work for my use case but they're not optimal.&lt;br&gt;
A proper evaluation dataset would help.&lt;/p&gt;

&lt;p&gt;Session memory is per-session only. The user knowledge base (SQLite in AppData) stores hardware profiles and usage patterns, but conversation context doesn't persist across restarts yet.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I'm Writing This
&lt;/h2&gt;

&lt;p&gt;Every "build an AI assistant" tutorial I found in 2026...&lt;br&gt;
starts with &lt;code&gt;pip install langchain&lt;/code&gt; or &lt;code&gt;pip install openai&lt;/code&gt;.&lt;br&gt;
Cloud API. Token costs. Internet required.&lt;br&gt;
That's fine for some use cases.&lt;/p&gt;

&lt;p&gt;But if you're building a desktop app that runs on someone else's machine, behind their firewall, on their data, you need a different approach.&lt;br&gt;
&lt;strong&gt;This is that approach:&lt;/strong&gt; a hybrid engine that's fast when it can be, smart when it needs to be, and never crashes because a server is down.&lt;/p&gt;

&lt;p&gt;PC Workman is open source, MIT licensed.&lt;br&gt;
The full AI engine is in &lt;code&gt;hck_gpt/&lt;/code&gt;- intent parser, hybrid engine, response builder, session memory, context builder.&lt;br&gt;
Read it, fork it, build something better.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Download the .exe (no Python needed): &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read the source: &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;github.com/HuckleR2003/PC_Workman_HCK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All my links: &lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;linktr.ee/marcin_firmuga&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you build something with a similar approach,&lt;br&gt;
or if you'd do it completely differently.&lt;br&gt;
I want to hear about it!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Marcin Firmuga, solo developer and founder of HCK_Labs.&lt;br&gt;
Building PC Workman publicly between retail shifts.&lt;br&gt;
**800+ hours, 25 GitHub stars&lt;/em&gt;&lt;em&gt;, and one offline AI engine that grew 9 layers when I wasn't looking.&lt;/em&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.amazonaws.com%2Fuploads%2Farticles%2Fgs21l05msxy81qadrdpy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs21l05msxy81qadrdpy.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow the build: &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://linkedin.com/in/marcinfirmuga" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="https://x.com/hck_lab" rel="noopener noreferrer"&gt;X&lt;/a&gt; · &lt;a href="https://medium.com/@marcinfirmuga" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why I Sign Every .exe With Sigstore - PC Workman v1.7.2 Release, Security-First Open Source</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Tue, 28 Apr 2026 21:43:04 +0000</pubDate>
      <link>https://dev.to/huckler/why-i-sign-every-exe-with-sigstore-pc-workman-v172-release-security-first-open-source-4pfh</link>
      <guid>https://dev.to/huckler/why-i-sign-every-exe-with-sigstore-pc-workman-v172-release-security-first-open-source-4pfh</guid>
      <description>&lt;p&gt;Someone tried to scare me with a security audit. It backfired.&lt;/p&gt;

&lt;p&gt;A few days ago, a stranger on the internet found PC Workman — my open-source system monitor — downloaded the .exe, and before running it, did what any sane person should do in 2026: they ran a full security audit.&lt;/p&gt;

&lt;p&gt;Not a quick VirusTotal check. A proper audit. They used Claude to analyze the codebase, the build pipeline, the permissions model, the network behavior, everything.&lt;/p&gt;

&lt;p&gt;Then they sent me the results. I think they expected me to panic.&lt;br&gt;
Instead I replied: "Can I see the full report?"&lt;/p&gt;

&lt;p&gt;They shared it. The audit confirmed what I already knew — clean code, no telemetry, no hidden network calls, no suspicious behavior. They ended up becoming a tester.&lt;/p&gt;

&lt;p&gt;This is the story of PC Workman v1.7.2, the biggest release in the project's history, and why security isn't something I added after the fact. It's baked into how I build.&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.amazonaws.com%2Fuploads%2Farticles%2Ffxe5438ks20gtwxur8c9.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.amazonaws.com%2Fuploads%2Farticles%2Ffxe5438ks20gtwxur8c9.png" alt=" " width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Nobody Trusts .exe Files Anymore (And Why They Shouldn't)
&lt;/h2&gt;

&lt;p&gt;Let's be honest. Downloading a random .exe from GitHub in 2026 is a trust exercise most people fail. And they're right to fail it.&lt;/p&gt;

&lt;p&gt;Open-source doesn't mean safe. It means auditable. The code being public is step one. But if you're shipping executables, you need to prove that the .exe you're distributing was actually built from that public code, wasn't tampered with, and doesn't phone home.&lt;/p&gt;

&lt;p&gt;Most solo developers skip this entirely. They push a PyInstaller build to releases, write "trust me bro" in the README, and wonder why downloads stay low.&lt;/p&gt;

&lt;p&gt;I decided early on that if PC Workman was going to ask for system-level access — reading CPU temperatures, monitoring processes, scanning Windows registry — then security couldn't be an afterthought.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Security Actually Looks Like in PC Workman
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Sigstore Digital Signatures
&lt;/h3&gt;

&lt;p&gt;Every release gets signed with Sigstore. This is the same signing infrastructure used by Kubernetes, npm, and PyPI. It creates a cryptographic proof that ties the executable to my GitHub identity and logs it in a public transparency ledger.&lt;/p&gt;

&lt;p&gt;Anyone can verify it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sigstore verify github PC_Workman_HCK_1.7.2.exe &lt;span class="nt"&gt;--bundle&lt;/span&gt; sigstore.bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the signature doesn't match, the file was tampered with. Don't run it.&lt;/p&gt;

&lt;h3&gt;
  
  
  VirusTotal — 70+ Engines, Every Release
&lt;/h3&gt;

&lt;p&gt;Before any .exe goes public, it gets uploaded to VirusTotal and scanned against 70+ antivirus engines. Current result for v1.7.2: 0 detections.&lt;/p&gt;

&lt;p&gt;You don't have to take my word for it. Go to virustotal.com, upload the file yourself, and check.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub CodeQL — Automated on Every Commit
&lt;/h3&gt;

&lt;p&gt;CodeQL runs on every push to main. It scans for common Python vulnerability patterns: injection attacks, path traversal, insecure deserialization, hardcoded secrets. If something triggers, it blocks the commit.&lt;/p&gt;

&lt;p&gt;This isn't something I run occasionally. It runs on every single commit, automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  SECURITY.md — 445 Lines of Policy
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcktsczcu1xphrnkd8ny5.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.amazonaws.com%2Fuploads%2Farticles%2Fcktsczcu1xphrnkd8ny5.png" alt=" " width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most GitHub repos either don't have a security policy, or they have a template that says "email me." PC Workman's SECURITY.md is 445 lines covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supported versions and update timeline&lt;/li&gt;
&lt;li&gt;How to report vulnerabilities (private GitHub reporting + email)&lt;/li&gt;
&lt;li&gt;Response timeline (24h acknowledgment, 72h validation, 7 days for critical fixes)&lt;/li&gt;
&lt;li&gt;CVSS severity classification&lt;/li&gt;
&lt;li&gt;Dependency management process&lt;/li&gt;
&lt;li&gt;Detailed verification instructions for every release&lt;/li&gt;
&lt;li&gt;FAQ addressing trust questions directly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It exists because if you're asking users to run your code with admin privileges, you owe them a complete answer to "why should I trust this?"&lt;/p&gt;

&lt;h3&gt;
  
  
  What PC Workman Does NOT Do
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No telemetry. Zero. Nothing phones home.&lt;/li&gt;
&lt;li&gt;No analytics. No tracking. No user profiling.&lt;/li&gt;
&lt;li&gt;No cloud dependency. Core monitoring is 100% offline.&lt;/li&gt;
&lt;li&gt;No data leaves your machine unless you explicitly use the optional AI features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The network section of the audit came back clean because there's nothing to find.&lt;/p&gt;




&lt;h2&gt;
  
  
  v1.7.2 — What Actually Changed
&lt;/h2&gt;

&lt;p&gt;Now for the release itself. The last downloadable .exe was v1.6.8 from March. That was a monitoring tool that collected data and showed it to you.&lt;/p&gt;

&lt;p&gt;v1.7.2 is a different animal. It acts on what it finds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid AI Engine (Complete hck_GPT Rewrite)
&lt;/h3&gt;

&lt;p&gt;The AI layer went from a single &lt;code&gt;chat_handler.py&lt;/code&gt; file to a modular engine with 5 subpackages: &lt;code&gt;engine/&lt;/code&gt;, &lt;code&gt;intents/&lt;/code&gt;, &lt;code&gt;memory/&lt;/code&gt;, &lt;code&gt;context/&lt;/code&gt;, &lt;code&gt;responses/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The routing logic is simple: known intents (stats, alerts, temperature, processes) hit the rule engine first. Fast, predictable, zero external dependency. Open-ended questions ("why is my PC slow right now?") get forwarded to Ollama — a local LLM that runs on your machine. No cloud API. No API key. No tokens.&lt;/p&gt;

&lt;p&gt;If Ollama isn't installed, the engine falls back gracefully. No crashes, no error messages about missing services. It just uses what it has.&lt;/p&gt;

&lt;p&gt;Every response is bilingual. Polish or English, auto-detected per message. The parser uses ASCII-fold dual scoring to handle Polish diacritics without breaking intent matching.&lt;/p&gt;

&lt;p&gt;There's also a proactive monitor running as a background daemon. It watches for sustained CPU pressure (&amp;gt;80% for 30 seconds), RAM warnings (&amp;gt;85%), throttling, low disk space, and long session uptime. When something triggers, it pushes an alert to the chat panel. You don't have to ask. It tells you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Startup Manager
&lt;/h3&gt;

&lt;p&gt;Full page that reads from three Windows registry hives (&lt;code&gt;HKCU&lt;/code&gt;, &lt;code&gt;HKLM&lt;/code&gt;, &lt;code&gt;WOW6432Node&lt;/code&gt;). No admin rights needed for reading. Knowledge base of 30 common programs with impact ratings (High/Medium/Low). Three panels: programs to optimize, programs safe to disable, and the full list.&lt;/p&gt;

&lt;p&gt;Disable means real &lt;code&gt;winreg.DeleteValue()&lt;/code&gt; — but only after a confirmation dialog. Nothing gets removed silently. User choices persist to JSON between sessions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Services Manager
&lt;/h3&gt;

&lt;p&gt;Catalogue of 40+ Windows services sorted into four categories: Essential (locked, can't be touched), Recommended, Optional, and Likely Unnecessary. Each row shows current status, startup type, and action buttons (Stop/Start/Restart).&lt;/p&gt;

&lt;p&gt;The interesting part is the TURBO Mode integration. You select which non-essential services should auto-stop when TURBO activates. When TURBO deactivates, they restore to their previous state. Selections persist between sessions. All changes get logged.&lt;/p&gt;

&lt;p&gt;Admin detection is built in — if you're not elevated, the manager shows a warning banner instead of pretending the buttons work and failing silently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimization Hub
&lt;/h3&gt;

&lt;p&gt;The old single "Optimization &amp;amp; Services" button in My PC Central got replaced with a 3-zone interactive Canvas widget. Left zone: Optimization Center. Top-right: Startup Manager with live registry entry count. Bottom-right: Services Manager with running service count. Hover brightens the active zone. Metrics update from a background daemon thread.&lt;/p&gt;

&lt;h3&gt;
  
  
  Everything Else
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;First Setup &amp;amp; Drivers page with arc gauge health score computed from driver ages and startup count. Reads directly from Windows registry. No internet, no third-party API.&lt;/li&gt;
&lt;li&gt;Dashboard nav buttons fully redesigned — dark gradients, bordeaux brackets, 7 vector icons drawn on Canvas (zero image files).&lt;/li&gt;
&lt;li&gt;Inter font via GDI32 with Segoe UI fallback.&lt;/li&gt;
&lt;li&gt;HCK_Labs and Guide pages redesigned as full blog layouts.&lt;/li&gt;
&lt;li&gt;Efficiency tab fixes: correct physical core count, per-core session stats, side-by-side TOP CPU/RAM consumers.&lt;/li&gt;
&lt;li&gt;4 new &lt;code&gt;query_api&lt;/code&gt; methods: temperature history, temperature summary, top processes lifetime, weekly comparison with trend detection.&lt;/li&gt;
&lt;li&gt;hck_GPT language bug fixed, temperature fallback fixed, unconditional TURBO tip removed.&lt;/li&gt;
&lt;li&gt;Complete .exe packaging rewrite: 25+ hidden imports, settings directory bundled, proper output naming.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version:&lt;/strong&gt; 1.7.2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commits since last .exe:&lt;/strong&gt; ~60&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New modules:&lt;/strong&gt; 8&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub stars:&lt;/strong&gt; 25&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Downloads:&lt;/strong&gt; ~100+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hours logged:&lt;/strong&gt; 800+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VirusTotal:&lt;/strong&gt; 0/70 detections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sigstore:&lt;/strong&gt; Signed and verified&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CodeQL:&lt;/strong&gt; Active on every commit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SECURITY.md:&lt;/strong&gt; 445 lines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telemetry:&lt;/strong&gt; None. Zero. Nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmxw07emn1wzrqmtj17a.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.amazonaws.com%2Fuploads%2Farticles%2Ftmxw07emn1wzrqmtj17a.png" alt=" " width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Ship .exe Files (And Why More Developers Should)
&lt;/h2&gt;

&lt;p&gt;Most open-source projects live and die on GitHub. The README says "clone the repo, install dependencies, run startup.py." That's fine for developers. For everyone else, the project doesn't exist.&lt;/p&gt;

&lt;p&gt;Shipping an executable is harder. You deal with PyInstaller nightmares (8 hours debugging hidden imports for v1.6.8), false positive antivirus detections, signing infrastructure, and the constant question of "how do I prove this is safe?"&lt;/p&gt;

&lt;p&gt;But it's also where the real feedback comes from. Source code users are patient. They expect rough edges. .exe users click the button and expect it to work. That's the standard worth building toward.&lt;/p&gt;

&lt;p&gt;v1.7.2 is the second .exe I've ever shipped. The first was v1.6.8 in March — a monitoring tool with placeholder buttons and a neon green Turbo Boost card. The app barely resembles that version now.&lt;/p&gt;

&lt;p&gt;If you want to try it, the .exe is on GitHub Releases. If you want to audit it first, the source is right there. If you want to verify the signature, the instructions are in SECURITY.md. If you find something wrong, the reporting process is documented.&lt;/p&gt;

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




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

&lt;p&gt;v1.7.3 through v1.7.8 will build out the TURBO suite: suspending inactive background processes, auto power plan switching, CPU core unparking, and full integration testing.&lt;/p&gt;

&lt;p&gt;v2.0 targets Microsoft Store publishing and Ollama as a first-class local AI option.&lt;/p&gt;

&lt;p&gt;Next week I start Umiejętności Jutra 3.0 — Google's AI certification program through SGH. First structured learning since I finished technikum. Curious how it'll shape the roadmap.&lt;/p&gt;

&lt;p&gt;PC Workman is open source, MIT licensed. 800+ hours of solo development between retail shifts. Still shipping. Still signing. Still scanning.&lt;/p&gt;

&lt;p&gt;Star the repo: &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;github.com/HuckleR2003/PC_Workman_HCK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All my links: &lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;linktr.ee/marcin_firmuga&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Marcin Firmuga, solo developer and founder of HCK_Labs. Building PC Workman publicly, honestly, between Żabka shifts. Follow the build: &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://linkedin.com/in/marcinfirmuga" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="https://x.com/hck_lab" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt; · &lt;a href="https://medium.com/@MarcinFirmuga" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>Wednesday Code Autopsy #4: The Canvas Arc Nobody Uses - PC Workman</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Thu, 16 Apr 2026 17:50:16 +0000</pubDate>
      <link>https://dev.to/huckler/wednesday-code-autopsy-4-the-canvas-arc-nobody-uses-pc-workman-oob</link>
      <guid>https://dev.to/huckler/wednesday-code-autopsy-4-the-canvas-arc-nobody-uses-pc-workman-oob</guid>
      <description>&lt;p&gt;Needed circular progress gauge. Googled "Python circular progress bar." Every answer: &lt;code&gt;pip install [library]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Drew mine with pure tkinter Canvas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero dependencies&lt;/li&gt;
&lt;li&gt;Two parameters: &lt;code&gt;style="arc"&lt;/code&gt;, &lt;code&gt;extent=-270&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Professional look&lt;/li&gt;
&lt;li&gt;20 lines of code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;secret:&lt;/strong&gt; tkinter has THREE arc styles. 99% of devs only use one.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I needed a circular progress gauge for PC Workman's "First Setup &amp;amp; Drivers" page.&lt;/p&gt;

&lt;p&gt;Something clean. Professional. The kind you see in system health dashboards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First instinct:&lt;/strong&gt; Google.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search:&lt;/strong&gt; "Python circular progress bar"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Results:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;matplotlib circular progress tutorial&lt;/li&gt;
&lt;li&gt;PIL + pillow gauge example&lt;/li&gt;
&lt;li&gt;PyQt QProgressBar subclass&lt;/li&gt;
&lt;li&gt;Custom tkinter widget library&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every answer started the same: &lt;code&gt;pip install [library]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;PC Workman is already PyQt6 + tkinter + psutil + SQLite. Adding matplotlib for one gauge? Overkill.&lt;/p&gt;

&lt;p&gt;There had to be a better way.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Discovery
&lt;/h2&gt;

&lt;p&gt;Opened the &lt;a href="https://docs.python.org/3/library/tkinter.html#canvas-objects" rel="noopener noreferrer"&gt;tkinter Canvas docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Not Stack Overflow. Not a tutorial. The &lt;strong&gt;actual documentation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Found &lt;code&gt;create_arc()&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;style:&lt;/strong&gt; One of 'pieslice' (default), 'chord', or &lt;strong&gt;'arc'&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;style="arc"&lt;/strong&gt; — draws just the arc itself. No fill. No center lines.&lt;/p&gt;

&lt;p&gt;This was it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution
&lt;/h2&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;_draw_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Background arc (full 270° track)
&lt;/span&gt;    &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#1f2937&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Progress arc (proportional to score)
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&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;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;_score_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;extent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&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;Result:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;[10-second PC Health gauge animation]&lt;/p&gt;

&lt;p&gt;Clean. Professional. Zero dependencies.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Geometry
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;create_arc()&lt;/code&gt; takes a &lt;strong&gt;bounding box&lt;/strong&gt;, not center + radius:&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;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt;
&lt;span class="c1"&gt;#                 └─────┬─────┘
#                 rectangle containing circle
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a perfect circle at (60, 60) with radius 50:&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;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt;
&lt;span class="c1"&gt;#                 60-50, 60-50, 60+50, 60+50
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbeolvjqnssprhnyrv369.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.amazonaws.com%2Fuploads%2Farticles%2Fbeolvjqnssprhnyrv369.png" alt=" " width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Angles
&lt;/h3&gt;

&lt;p&gt;tkinter measures angles from &lt;strong&gt;East (3 o'clock) = 0°&lt;/strong&gt;, counterclockwise:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Direction&lt;/th&gt;
&lt;th&gt;Degrees&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;East&lt;/td&gt;
&lt;td&gt;0°&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;North&lt;/td&gt;
&lt;td&gt;90°&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;West&lt;/td&gt;
&lt;td&gt;180°&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;South&lt;/td&gt;
&lt;td&gt;270°&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Trick:&lt;/strong&gt; Negative &lt;code&gt;extent&lt;/code&gt; goes &lt;strong&gt;clockwise&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a speedometer (7:30 to 4:30 position):&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;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# 225° = bottom-left (7:30)
&lt;/span&gt;&lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt;  &lt;span class="c1"&gt;# -270° clockwise = wraps to bottom-right (4:30)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect 270° gauge.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Secret Third Style
&lt;/h3&gt;

&lt;p&gt;Most devs know two Canvas arc styles:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Style&lt;/th&gt;
&lt;th&gt;What It Draws&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;"pieslice"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filled wedge from center (default)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;"chord"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Arc + straight line connecting ends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;"arc"&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Just the arc curve&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Almost nobody uses &lt;code&gt;style="arc"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's your circular progress bar.&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;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#10b981&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7-pixel green arc. No fill. No custom drawing.&lt;br&gt;
&lt;strong&gt;style="arc"&lt;/strong&gt; has been in tkinter since Python 1.x. 99% of developers have never touched it.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Production Implementation
&lt;/h2&gt;

&lt;p&gt;The two-line example is simplified. Here's what ships in PC Workman:&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;_draw_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;W&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;92&lt;/span&gt;
    &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;W&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;

    &lt;span class="c1"&gt;# Layer 1: Outer glow (wider, darker)
&lt;/span&gt;    &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#1a2035&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Layer 2: Track (gray path)
&lt;/span&gt;    &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#1f2937&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Layer 3: Progress (colored, proportional)
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&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;col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;_score_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;extent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Score text
&lt;/span&gt;        &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                          &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font&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;Consolas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#6b7280&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font&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;Consolas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&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;Three layers on same Canvas:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Outer glow&lt;/strong&gt; — 10px dark, 4px larger radius (depth)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track&lt;/strong&gt; — 7px gray, full 270° (background)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progress&lt;/strong&gt; — 7px colored, proportional (gauge)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No masking. No blending. Just stacking arcs.&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.amazonaws.com%2Fuploads%2Farticles%2F1ftdl9caznp8z2j9dayf.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.amazonaws.com%2Fuploads%2Farticles%2F1ftdl9caznp8z2j9dayf.png" alt=" " width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Math
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;extent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Calculation&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;100&lt;/td&gt;
&lt;td&gt;-int(270 * 1.0)&lt;/td&gt;
&lt;td&gt;-270 (full)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;td&gt;-int(270 * 0.75)&lt;/td&gt;
&lt;td&gt;-202 (¾)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;-int(270 * 0.5)&lt;/td&gt;
&lt;td&gt;-135 (½)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;-int(270 * 0.0)&lt;/td&gt;
&lt;td&gt;0 (empty)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;int()&lt;/code&gt; is critical.&lt;/strong&gt; tkinter won't accept float extents — it'll silently fail and draw nothing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Color Grading
&lt;/h2&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;_score_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&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;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#10b981&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Green
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#fbbf24&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Amber
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#ef4444&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;      &lt;span class="c1"&gt;# Red
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_score_grade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&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;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EXCELLENT&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;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOD&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;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FAIR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POOR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three thresholds. Same color in arc, number, and label.&lt;/p&gt;

&lt;p&gt;No color library. Just hex values.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Scanning State
&lt;/h2&gt;

&lt;p&gt;Gauge drawn twice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;On load&lt;/strong&gt; — gray track only (&lt;code&gt;score=None&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After scan&lt;/strong&gt; — colored progress (&lt;code&gt;score=0-100&lt;/code&gt;)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Initial
&lt;/span&gt;&lt;span class="nf"&gt;_draw_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;health_canvas&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;# After scan thread
&lt;/span&gt;&lt;span class="nf"&gt;_draw_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;health_canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calculated_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;if score is not None&lt;/code&gt; prevents empty arc or crash.&lt;/p&gt;

&lt;p&gt;While scanning (registry check, driver status, updates), gauge waits as clean gray circle.&lt;/p&gt;




&lt;h2&gt;
  
  
  Copyable Minimal Example
&lt;/h2&gt;

&lt;p&gt;Want this in your project? Here's the stripped version:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tkinter&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Tk&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Canvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#0a0e14&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;canvas&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;draw_gauge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Gray track
&lt;/span&gt;    &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#1f2937&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Colored progress
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;extent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;270&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#10b981&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Text
&lt;/span&gt;        &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                          &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;white&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font&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;Consolas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nf"&gt;draw_gauge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mainloop&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;20 lines. Zero dependencies. Production-ready.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;This gauge powers health check in &lt;strong&gt;PC Workman&lt;/strong&gt; (110+ downloads, 23 GitHub stars).&lt;br&gt;
First thing users see in "First Setup &amp;amp; Drivers."&lt;/p&gt;

&lt;p&gt;Makes the section feel premium — smooth, clean, not default tkinter.&lt;br&gt;
All because I read Canvas docs instead of installing matplotlib.&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.amazonaws.com%2Fuploads%2Farticles%2Fdzxq20tj4msgw37vn2cf.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.amazonaws.com%2Fuploads%2Farticles%2Fdzxq20tj4msgw37vn2cf.png" alt=" " width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Lesson
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Most developers solve problems by adding dependencies.&lt;br&gt;
Need progress bar? Install library.&lt;br&gt;&lt;br&gt;
Need chart? Install library.&lt;br&gt;&lt;br&gt;
Need widget? Install library.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nothing wrong with libraries. Good ones save time.&lt;br&gt;
&lt;strong&gt;But sometimes the best solution is in stdlib docs.&lt;/strong&gt;&lt;br&gt;
In a parameter you've never used.&lt;br&gt;
On a page you've never read.&lt;br&gt;
&lt;strong&gt;style="arc"&lt;/strong&gt; has existed since Python 1.x.&lt;br&gt;
99% of developers never touched it.&lt;br&gt;
I found it in 5 minutes of reading docs instead of Googling "how to."&lt;/p&gt;




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

&lt;p&gt;PC Workman v1.7.x builds toward &lt;strong&gt;TURBO Mode&lt;/strong&gt;. Windows optimization tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU unparking&lt;/li&gt;
&lt;li&gt;RAM flushing&lt;/li&gt;
&lt;li&gt;Service management&lt;/li&gt;
&lt;li&gt;Power plan switching&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"First Setup &amp;amp; Drivers" scans system, gives health score before TURBO touches anything.&lt;/p&gt;

&lt;p&gt;This gauge is part of that foundation.&lt;/p&gt;

&lt;p&gt;v1.7.2 ships next week.&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;What's your "I can't believe this is possible with just X" moment?&lt;/strong&gt;&lt;br&gt;
Time you almost installed library, then realized solution was in docs?&lt;br&gt;
Drop it below &lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PC Workman:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK/releases" rel="noopener noreferrer"&gt;Releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK#readme" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK/releases/latest" rel="noopener noreferrer"&gt;Download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Follow the build:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;X: &lt;a href="https://twitter.com/hck_lab" rel="noopener noreferrer"&gt;@hck_lab&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://linkedin.com/in/marcinfirmuga" rel="noopener noreferrer"&gt;Marcin Firmuga&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;All links: &lt;a href="https://linktr.ee/hck_labs" rel="noopener noreferrer"&gt;linktr.ee/hck_labs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Wednesday Code Autopsy continues next week.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Building PC Workman in public. One arc at a time.&lt;/p&gt;

</description>
      <category>python</category>
      <category>buildinpublic</category>
      <category>opensource</category>
      <category>github</category>
    </item>
    <item>
      <title>PC Workman v1.7.2: I Built a Driver Booster Competitor From Scratch, Fixes. Monday Grind Blueprint #3</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Mon, 13 Apr 2026 12:40:56 +0000</pubDate>
      <link>https://dev.to/huckler/pc-workman-v172-i-built-a-driver-booster-competitor-from-scratch-fixes-monday-grind-blueprint-3393</link>
      <guid>https://dev.to/huckler/pc-workman-v172-i-built-a-driver-booster-competitor-from-scratch-fixes-monday-grind-blueprint-3393</guid>
      <description>&lt;p&gt;6 AM. Monday. Couldn't sleep.&lt;/p&gt;

&lt;p&gt;Not the inspirational "I'm so motivated" kind of can't sleep. More like my brain decided to start compiling the entire weekly sprint at 5:47 AM and wouldn't shut up until I opened VS Code.&lt;/p&gt;

&lt;p&gt;By 11 AM I had shipped four things that weren't even on this week's list. By Friday, the actual plan got done too. Some of it. Enough of it. This is the story of both.&lt;/p&gt;

&lt;p&gt;PC Workman is at v1.7.2 now. If you're new here: it's an open-source AI-powered system monitor I've been building solo for 800+ hours. Python, PyQt5, WMI, a custom AI diagnostic engine called hck_GPT, and a lot of late nights after Żabka shifts. This week was one of the heaviest since I started.&lt;/p&gt;

&lt;p&gt;Let's cut it open.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. hck_GPT Time Badges — The Small Feature That Took Months to Actually Do
&lt;/h2&gt;

&lt;p&gt;This one has been haunting me since Monday Grind Blueprint #1.&lt;/p&gt;

&lt;p&gt;The problem was simple: hck_GPT would tell you things like "Chrome ate 6GB RAM recently." When recently? An hour ago? Yesterday? During that Windows update at 3 AM?&lt;/p&gt;

&lt;p&gt;No timestamp. No context. Just "recently."&lt;/p&gt;

&lt;p&gt;I kept pushing it back. "Next sprint." "After the UI redesign." "When I have time." Classic.&lt;/p&gt;

&lt;p&gt;Monday morning, 6:23 AM, I just... did it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Interesting Part
&lt;/h3&gt;

&lt;p&gt;hck_GPT's chat panel is a &lt;code&gt;tk.Text&lt;/code&gt; widget. Most people use Text widgets for plain text. Type stuff in, maybe color some words, done.&lt;/p&gt;

&lt;p&gt;But tkinter has this thing called &lt;code&gt;window_create()&lt;/code&gt; that lets you embed &lt;em&gt;any widget&lt;/em&gt; inside the text flow. Not on top of it. Not floating above it. &lt;em&gt;Inside&lt;/em&gt; it, like it's just another character.&lt;/p&gt;

&lt;p&gt;So instead of prepending "[08:52]" as plain text (boring, hard to style, breaks if the message wraps weird), I built a tiny canvas badge:&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;# panel.py
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_make_time_badge&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;badge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Canvas&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;log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bg_panel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;highlightthickness&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;badge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_rectangle&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#0d0f14&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&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;badge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_rectangle&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#dc2626&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# left red bar
&lt;/span&gt;    &lt;span class="n"&gt;badge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;59&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="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#dc2626&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# right red bar
&lt;/span&gt;    &lt;span class="n"&gt;badge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#374151&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;badge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&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;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%H:%M&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                      &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#94a3b8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font&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;Consolas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bold&lt;/span&gt;&lt;span class="sh"&gt;"&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;badge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dark background, red accent bars on each side, Consolas font, 7pt bold. It looks like a tiny terminal badge sitting in the chat.&lt;/p&gt;

&lt;p&gt;Then in &lt;code&gt;add_message()&lt;/code&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_message&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;msg&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;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;normal&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;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hck_GPT:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;badge&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;_make_time_badge&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;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;window_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;badge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pady&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;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end&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; &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;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&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;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;disabled&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;That &lt;code&gt;window_create("end", window=badge)&lt;/code&gt; is the whole trick. The canvas lives inside the text flow, scrolls with everything else, and costs almost nothing performance-wise.&lt;/p&gt;

&lt;p&gt;Small feature. One morning. Months overdue. Now every hck_GPT message says &lt;em&gt;when&lt;/em&gt; it happened. 08:52, not "a while ago."&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.amazonaws.com%2Fuploads%2Farticles%2Fw9zb3o4sepunzgjj5yv3.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.amazonaws.com%2Fuploads%2Farticles%2Fw9zb3o4sepunzgjj5yv3.png" alt=" " width="799" height="306"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Process Library — From "Unknown" to "Oh, That's What You Are"
&lt;/h2&gt;

&lt;p&gt;This one started in Blueprint #1 too. The idea was simple: when PC Workman mentions a process, you should know what it is without opening Google.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;process_library.json&lt;/code&gt; already had ~60 entries. But real usage kept surfacing gaps. hck_GPT would say "WmiPrvSE.exe is using 34% CPU" and the tooltip showed... nothing. Unknown process.&lt;/p&gt;

&lt;p&gt;This week I added 8 more entries, specifically the ones that kept showing up as unknowns during actual sessions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;wmiprvse.exe&lt;/code&gt; — WMI Provider Host. Every monitoring tool talks to this. Including PC Workman itself.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;msmpeng.exe&lt;/code&gt; — Windows Defender's scan engine. The one that randomly spikes CPU at 2 AM.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;registry&lt;/code&gt; — NT kernel process, no .exe extension. Easy to miss entirely.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claude.exe&lt;/code&gt; — Yes, the Claude desktop app. I use it enough that it shows up in Top 5.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hitman.exe&lt;/code&gt;, &lt;code&gt;hitman2.exe&lt;/code&gt;, &lt;code&gt;hitman3.exe&lt;/code&gt; — HITMAN trilogy. Each one with different VRAM profiles.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;datatransfer.exe&lt;/code&gt; — Connected Devices Platform sync. Nobody knows what this is until it's eating RAM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each entry follows the same schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"msmpeng.exe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Windows Defender Antimalware Service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vendor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Microsoft"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Core scan engine for Windows Defender. Periodic CPU spikes are normal during scheduled scans."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"power_usage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"medium-high during scans"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"safety"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"safe — do not kill"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typical_cpu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0-5% idle, 15-40% during scan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typical_ram"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"150-300 MB"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2hfdv57rfaktba3g443.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2hfdv57rfaktba3g443.gif" alt=" " width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clean, queryable, and every field actually means something.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tooltips Everywhere, Not Just in Chat
&lt;/h3&gt;

&lt;p&gt;Before this week, the hover tooltip only worked inside hck_GPT's chat panel. If a process showed up in the main dashboard Top 5 panels, you were on your own.&lt;/p&gt;

&lt;p&gt;Fixed that. But it wasn't as simple as "just add a tooltip."&lt;/p&gt;

&lt;p&gt;The Top 5 panels update every render tick. Process names change constantly. If you capture the process name at widget creation time, the tooltip will show stale data within seconds.&lt;/p&gt;

&lt;p&gt;Solution: store the process name in a mutable dict that gets updated every tick:&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;# main_window_expanded.py
&lt;/span&gt;&lt;span class="n"&gt;widget_data&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;row&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name_lbl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu_bar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cpu_bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu_val&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cpu_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ram_bar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ram_bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ram_val&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ram_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proc_name&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="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# updated every render tick
&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_process_tooltip&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;_enter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;widget_data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;pn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wd&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proc_name&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;pn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;tt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_proc_lib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format_tooltip_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pn&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;tt&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;_process_tooltip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tt&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;_leave&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&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;_process_tooltip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;name_lbl&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;Enter&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;_enter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;row&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;Enter&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;_enter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# whole row = bigger hit area
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in the render loop, 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;widget_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proc_name&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;display_name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;wd=widget_data&lt;/code&gt; in the lambda captures by reference, not by value. So when the render loop updates &lt;code&gt;proc_name&lt;/code&gt;, the tooltip reads the fresh name. No timer, no polling, no auto-hide. Mouse in = tooltip. Mouse out = gone. User reads at their own pace.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. First Setup &amp;amp; Drivers — Building a Driver Booster From Scratch
&lt;/h2&gt;

&lt;p&gt;This was the big one. Not planned for Monday. Not planned for this week at all. Just... happened.&lt;/p&gt;

&lt;p&gt;I opened Driver Booster, IObit's tool, the one everyone installs when they get a new PC. And I thought: what does it actually &lt;em&gt;do&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;It reads your installed drivers. Checks versions. Shows you what's outdated. That's it. The "boost" part is just a download link.&lt;/p&gt;

&lt;p&gt;I can do that. Without internet. Without admin rights. Without a third-party API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading Drivers From the Windows Registry
&lt;/h3&gt;

&lt;p&gt;Windows stores driver metadata in the registry under &lt;code&gt;SYSTEM\CurrentControlSet\Control\Class\{GUID}&lt;/code&gt;. Each device class (GPU, Audio, Network, USB) has its own GUID. You open the key, enumerate subkeys, and read three values: &lt;code&gt;DriverDesc&lt;/code&gt;, &lt;code&gt;DriverVersion&lt;/code&gt;, &lt;code&gt;DriverDate&lt;/code&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_read_class_driver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;guid&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;key_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;fr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SYSTEM\CurrentControlSet\Control\Class\{guid}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;OpenKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HKEY_LOCAL_MACHINE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cls&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;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;QueryInfoKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&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="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;sn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;EnumKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&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;sn&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;OpenKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;desc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;QueryValueEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DriverDesc&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kw&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&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;kw&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_SKIP&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="n"&gt;ver&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;QueryValueEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DriverVersion&lt;/span&gt;&lt;span class="sh"&gt;"&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;drv_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;QueryValueEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DriverDate&lt;/span&gt;&lt;span class="sh"&gt;"&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;drv_date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No internet call. No admin popup. Just &lt;code&gt;winreg.OpenKey&lt;/code&gt; on &lt;code&gt;HKEY_LOCAL_MACHINE&lt;/code&gt;. Windows lets you &lt;em&gt;read&lt;/em&gt; this without elevation. You just can't &lt;em&gt;write&lt;/em&gt; to it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;_SKIP&lt;/code&gt; list filters out virtual network adapters (Hyper-V, VPN clients, Docker). Without it, the page fills up with phantom devices nobody cares about.&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.amazonaws.com%2Fuploads%2Farticles%2Fpddbtk95lf4ah74pdxsz.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.amazonaws.com%2Fuploads%2Farticles%2Fpddbtk95lf4ah74pdxsz.png" alt=" " width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Date Format Problem
&lt;/h3&gt;

&lt;p&gt;Driver dates come from the registry as strings. Sounds simple. Except Windows uses at least three different formats depending on... I honestly don't know what. Device class? Driver manufacturer? Phase of the moon?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MM-DD-YYYY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;YYYY-MM-DD&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;YYYYMMDD&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;_driver_age_days()&lt;/code&gt; function tries all three. If none work, it returns &lt;code&gt;None&lt;/code&gt; and the health score takes a small penalty for "unknown age" instead of crashing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Health Score — Computed, Not Faked
&lt;/h3&gt;

&lt;p&gt;Driver Booster shows you a big number. "Your system health: 73%." Where does that number come from? Nobody knows.&lt;/p&gt;

&lt;p&gt;Mine is transparent:&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;_compute_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drivers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;startup_count&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;drivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;_driver_age_days&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&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;date&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="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;days&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;score&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;startup_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;startup_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Driver older than a year? Minus 20. Unknown date? Minus 6. Too many startup programs? Penalty. The formula is right there. You can read it, disagree with it, and fork it.&lt;/p&gt;

&lt;p&gt;The score renders as an arc gauge drawn with &lt;code&gt;canvas.create_arc()&lt;/code&gt;. 270° sweep, green→amber→red based on value. Nothing fancy. Nothing hidden.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Actions
&lt;/h3&gt;

&lt;p&gt;The page also has a Quick Actions panel. One-click access to Device Manager, Services, System Info, and MSConfig. These are just &lt;code&gt;subprocess.Popen&lt;/code&gt; calls to &lt;code&gt;devmgmt.msc&lt;/code&gt;, &lt;code&gt;services.msc&lt;/code&gt;, &lt;code&gt;msinfo32.exe&lt;/code&gt;, and &lt;code&gt;msconfig.exe&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sounds trivial. But I deep-researched what other tools in this space offer for first-time PC setup, and most of them... don't offer this. They focus on the driver scan and ignore the fact that someone setting up a new machine probably also wants quick access to system tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architecture Bit
&lt;/h3&gt;

&lt;p&gt;The page itself is ~370 lines (&lt;code&gt;ui/pages/first_setup_drivers.py&lt;/code&gt;). UI builds immediately — instant render, no loading screen. The driver scan runs in a &lt;code&gt;threading.Thread&lt;/code&gt; and posts results back to the main thread via &lt;code&gt;sf.after(0, lambda: _apply(...))&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Startup programs come from two registry hives:&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;paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HKEY_CURRENT_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SOFTWARE\Microsoft\Windows\CurrentVersion\Run&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;User&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;span class="n"&gt;winreg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HKEY_LOCAL_MACHINE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SOFTWARE\Microsoft\Windows\CurrentVersion\Run&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;System&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;User-level and system-level. Both matter.&lt;/p&gt;

&lt;p&gt;There's also a setup checklist that persists to &lt;code&gt;data/cache/setup_checklist.json&lt;/code&gt;. Toggle items on click, progress bar updates live. Small thing, but it makes the page feel like a tool you come back to, not a one-time scan.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Bug Nobody Noticed
&lt;/h2&gt;

&lt;p&gt;The "First Setup &amp;amp; Drivers" button in &lt;code&gt;yourpc_page.py&lt;/code&gt; was routing to the wrong page.&lt;/p&gt;

&lt;p&gt;Click "First Setup &amp;amp; Drivers" → opens the optimization wizard. Not the setup page. The optimization wizard worked fine, so nobody reported it. Including me. I was clicking through the sidebar, not through the yourpc page buttons.&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 (wrong):
&lt;/span&gt;&lt;span class="n"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&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;_nav_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;optimization_wizard&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# After (correct):
&lt;/span&gt;&lt;span class="n"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&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;_nav_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;first_setup&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;One line. Probably been wrong since the button was created. The sidebar badge now also shows the live checklist state (e.g., "3/6 done"), loaded from JSON on every render.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. The Scars
&lt;/h2&gt;

&lt;p&gt;Every week has them. Here are this week's:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The scroll_frame width trap.&lt;/strong&gt; When you embed a &lt;code&gt;tk.Frame&lt;/code&gt; inside a &lt;code&gt;tk.Canvas&lt;/code&gt; via &lt;code&gt;create_window&lt;/code&gt;, the frame doesn't automatically fill the canvas width. Your entire page content renders in a narrow strip on the left. All your &lt;code&gt;fill="x"&lt;/code&gt; packs are filling a 1px-wide frame and you don't know why.&lt;/p&gt;

&lt;p&gt;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;win_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_window&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;wrap&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;Configure&amp;gt;&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="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;itemconfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;win_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One binding. Took me 10 minutes of staring at the screen to figure out. If you're doing scrollable frames in tkinter — bookmark this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The dead-code ghost.&lt;/strong&gt; Earlier in the project, I deleted a &lt;code&gt;_build_yourpc_page_OLD_REMOVED&lt;/code&gt; function. But a nested function inside it (&lt;code&gt;_build_sensors_page_placeholder&lt;/code&gt;) survived the edit because the first attempt only replaced the function header, leaving the body orphaned. 40 lines of dead code sitting there, not breaking anything, not doing anything. Just vibing. Had to go back and kill it properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The write tool rejection.&lt;/strong&gt; After writing ~370 lines for the new Setup &amp;amp; Drivers page, the file write failed because a linter touched the file between read and write. Had to re-read and re-issue the entire write. Not a code problem. Workflow problem. Lesson: on large files, write in one shot without anything touching the file in between.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Coming — The Week Plan (v1.7.2 → v1.7.4)
&lt;/h2&gt;

&lt;p&gt;This was the Monday Grind Blueprint #3 plan. Here's what's on the board:&lt;/p&gt;

&lt;h3&gt;
  
  
  Dashboard Button Redesign
&lt;/h3&gt;

&lt;p&gt;The buttons work. They look like 2015. PIL-generated gradients, canvas caching for button states, CSS-like hover system with state tracking. Zero FPS impact — gradients are pre-rendered once on init, then reused. The purple color scheme stays.&lt;/p&gt;

&lt;h3&gt;
  
  
  System Cleanup Utilities
&lt;/h3&gt;

&lt;p&gt;Temp files cleaner (&lt;code&gt;%temp%&lt;/code&gt;, &lt;code&gt;Windows\Temp&lt;/code&gt;, Prefetch, browser caches). Log file manager with archive-before-delete. Startup optimizer with enable/disable toggles and impact ratings (High/Medium/Low).&lt;/p&gt;

&lt;p&gt;One rule that won't change: &lt;strong&gt;nothing gets deleted without explicit user confirmation.&lt;/strong&gt; No "we cleaned 2.3 GB!" surprises. You see the size, you confirm, then it happens. Detailed log of everything that was removed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete "My PC" Health Tab
&lt;/h3&gt;

&lt;p&gt;Right now: pretty placeholder. This week: real hardware detection via WMI queries (&lt;code&gt;Win32_Processor&lt;/code&gt;, &lt;code&gt;Win32_VideoController&lt;/code&gt;), temperature warnings (&amp;gt;85°C yellow, &amp;gt;90°C red), uptime stats, and JSON export for the health report.&lt;/p&gt;

&lt;h3&gt;
  
  
  TURBO — Auto RAM Flush
&lt;/h3&gt;

&lt;p&gt;The one I'm most curious about. Advanced SystemCare and CCleaner claim 300-800 MB freed. What are they actually doing?&lt;/p&gt;

&lt;p&gt;Researching three approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;EmptyStandbyList.exe&lt;/code&gt; (Sysinternals) — clears standby list&lt;/li&gt;
&lt;li&gt;Native Python via &lt;code&gt;ctypes&lt;/code&gt; (&lt;code&gt;SetSystemFileCacheSize&lt;/code&gt;) — direct kernel call&lt;/li&gt;
&lt;li&gt;Gentle per-process working set flush — least aggressive&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Trigger: RAM &amp;gt;75% for &amp;gt;30 seconds. Measure before/after. Show the user exactly how much was freed. Toggle on/off, threshold adjustable.&lt;/p&gt;

&lt;p&gt;If it works reliably without causing instability, it becomes the first real TURBO feature in PC Workman.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Version: 1.7.2&lt;/li&gt;
&lt;li&gt;Hours logged: 800+&lt;/li&gt;
&lt;li&gt;GitHub stars: 23&lt;/li&gt;
&lt;li&gt;Downloads: ~100&lt;/li&gt;
&lt;li&gt;Roadmap issues: 17 tracked, 4 done, 7 in review&lt;/li&gt;
&lt;li&gt;Retail shifts between coding sessions: 5 per week&lt;/li&gt;
&lt;li&gt;Microsoft Store: Q4 2026&lt;/li&gt;
&lt;li&gt;Sleep this week: not enough&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;I started PC Workman on a laptop hitting 94°C during compilation. Got fired three days before Christmas. Moved back to Poland. Started working at Żabka to pay bills while I keep building.&lt;/p&gt;

&lt;p&gt;This isn't a weekend project. It's 800+ hours of "I refuse to let another project die at 70%."&lt;/p&gt;

&lt;p&gt;v1.7.2 is the most feature-complete version yet. The First Setup &amp;amp; Drivers page alone competes with tools people pay for. The process library makes hck_GPT actually useful instead of just impressive. The timestamps make diagnostics real instead of vague.&lt;/p&gt;

&lt;p&gt;And we're not even at v2.0 yet.&lt;/p&gt;

&lt;p&gt;If you're building something solo, between shifts, between life — I see you. Keep shipping. Even the messy weeks count.&lt;/p&gt;

&lt;p&gt;Star the repo if you want to follow along: &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;github.com/HuckleR2003/PC_Workman_HCK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All my links: &lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;linktr.ee/marcin_firmuga&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Monday Grind Blueprint sets the bar.&lt;br&gt;
Wednesday Code Autopsy cuts it open.&lt;br&gt;
Friday Shipped &amp;amp; Scarred shows what actually happened.&lt;/p&gt;

&lt;p&gt;See you Wednesday.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;About the Author&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I'm Marcin Firmuga. Solo developer and founder of HCK_Labs. Building PC Workman — an open-source AI-powered system monitor — from scratch, publicly, honestly. Before this: game translations, IT technician internships, warehouse shifts in the Netherlands, and twelve failed projects I never finished. This one stuck.&lt;/em&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.amazonaws.com%2Fuploads%2Farticles%2Fnb6yo3bn8n0vc5t4vhvu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb6yo3bn8n0vc5t4vhvu.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow the build: &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://x.com/hck_lab" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt; · &lt;a href="https://linkedin.com/in/marcinfirmuga" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="https://medium.com/@MarcinFirmuga" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>python</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Friday Shipped &amp; Scarred #3: PC Workman 1.7.1, The Foundation Great Release</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Fri, 10 Apr 2026 08:32:02 +0000</pubDate>
      <link>https://dev.to/huckler/friday-shipped-scarred-3-pc-workman-171-the-foundation-great-release-10aj</link>
      <guid>https://dev.to/huckler/friday-shipped-scarred-3-pc-workman-171-the-foundation-great-release-10aj</guid>
      <description>&lt;p&gt;&lt;strong&gt;PC Workman v1.7.1 shipped this morning:&lt;/strong&gt;&lt;br&gt;
18 test cases rewritten (previously broken)&lt;br&gt;&lt;br&gt;
~130 lines dead code removed&lt;br&gt;
UI component refactor (AnimatedBar class)&lt;br&gt;&lt;br&gt;
3 chart bugs fixed (startup blank screen, filter lag, color inconsistency)&lt;br&gt;&lt;br&gt;
Process display redesign (readability improvements)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No new monitoring features.&lt;/strong&gt; That's the point. This is infrastructure for TURBO Mode (system optimization tools coming in 1.7.x series).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Python, PyQt6, tkinter, psutil, SQLite&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Dev time:&lt;/strong&gt; Single morning (flow state after 9h retail shift)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Community impact:&lt;/strong&gt; Closed testing issue from @Mary-devz&lt;/p&gt;


&lt;h2&gt;
  
  
  The Plan vs The Reality
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Monday's roadmap:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 issues from 1.7.8 milestone&lt;/li&gt;
&lt;li&gt;UI button redesign&lt;/li&gt;
&lt;li&gt;Code optimization in hck_gpt/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What actually happened:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tuesday-Wednesday: Schema.org validator debugging&lt;/li&gt;
&lt;li&gt;Thursday: 9h Żabka shift → 00:30 home → 5.5h sleep&lt;/li&gt;
&lt;li&gt;Friday 6 AM: Flow state activated → full release shipped&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Not what I planned. Better than what I planned.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Dead Code Archaeology
&lt;/h2&gt;

&lt;p&gt;Fast-moving projects accumulate technical debt. PC Workman went from simple psutil wrapper to multi-module platform in ~12 months. That speed left artifacts.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example: main_window_expanded.py
&lt;/h3&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;_build_yourpc_page_OLD_REMOVED&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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Old implementation of Your PC page.
    Extracted to ui/components/yourpc_page.py in v1.5.2
    ~130 lines of dead UI code
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# ... 130 lines that haven't been called in 4 months
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; Not connected to anything. Never called. Just cognitive overhead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; Delete. Entire function removed.&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.amazonaws.com%2Fuploads%2Farticles%2Fvajdzu08wz36dkgunass.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvajdzu08wz36dkgunass.gif" alt=" " width="599" height="313"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Example: core/monitor.py
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;platform&lt;/span&gt;  &lt;span class="c1"&gt;# Used: never
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;psutil&lt;/span&gt;    &lt;span class="c1"&gt;# Used: everywhere
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; Remove unused import.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Example: requirements.txt
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tkinter
tk&amp;gt;=0.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; Both are stdlib. Neither is pip-installable. Silent failures on &lt;code&gt;pip install -r requirements.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; Remove both. Document stdlib dependencies in README instead.&lt;/p&gt;


&lt;h2&gt;
  
  
  Test Suite Rewrite: From Broken to Verified
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Before (test_monitor.py):
&lt;/h3&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;test_monitor_has_read&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;monitor&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="c1"&gt;# ❌ Method doesn't exist
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cpu_percent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Actual method:&lt;/strong&gt; &lt;code&gt;monitor.read_snapshot()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This test has &lt;strong&gt;never passed.&lt;/strong&gt; It was never run.&lt;/p&gt;


&lt;h3&gt;
  
  
  After (test_monitor.py):
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;core.monitor.psutil.cpu_percent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;45.2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;core.monitor.psutil.virtual_memory&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;core.monitor.psutil.disk_usage&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;core.monitor.psutil.net_io_counters&lt;/span&gt;&lt;span class="sh"&gt;'&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;test_read_snapshot_keys&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;mock_net&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_disk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_mem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_cpu&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Snapshot contains all required keys with correct types&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;mock_mem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;62.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;mock_disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;78.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;mock_net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_sent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_recv&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_snapshot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cpu_percent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;
    &lt;span class="k"&gt;assert&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;snapshot&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cpu_percent&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;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ram_percent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Changes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;psutil fully mocked (no live system dependency)&lt;/li&gt;
&lt;li&gt;Actual method name used&lt;/li&gt;
&lt;li&gt;Type validation added&lt;/li&gt;
&lt;li&gt;Runs in CI without hardware&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Test Coverage Summary
&lt;/h2&gt;
&lt;h3&gt;
  
  
  test_monitor.py (7 cases)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Snapshot key presence &amp;amp; types&lt;/li&gt;
&lt;li&gt;Process list parsing correctness&lt;/li&gt;
&lt;li&gt;Sort order (CPU, RAM)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;top_processes(n)&lt;/code&gt; limit enforcement&lt;/li&gt;
&lt;li&gt;Cache hit behavior&lt;/li&gt;
&lt;li&gt;Background thread population timing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  test_analyzer.py (7 cases)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Zero-buffer edge case (should return zeroes)&lt;/li&gt;
&lt;li&gt;CPU average calculation accuracy&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;averages_now_1h_4h()&lt;/code&gt; structure validation&lt;/li&gt;
&lt;li&gt;Timestamp-based sample filtering&lt;/li&gt;
&lt;li&gt;Spike detection (clear jump vs stable values)&lt;/li&gt;
&lt;li&gt;Threshold sensitivity&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  test_avg_calculator.py (4 cases)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Missing file handling (empty list return)&lt;/li&gt;
&lt;li&gt;Single-day aggregation with known values&lt;/li&gt;
&lt;li&gt;Multi-day split (separate avg per date)&lt;/li&gt;
&lt;li&gt;Result dict key validation&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Total:&lt;/strong&gt; 18 test cases, all using &lt;code&gt;unittest.mock&lt;/code&gt;, zero live system dependencies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; TURBO Mode features (coming soon) will mutate system state. Verified data pipeline baseline is essential.&lt;/p&gt;


&lt;h2&gt;
  
  
  UI Component: AnimatedBar
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Bars updated instantly:&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 - instant jump
&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;cpu_bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;place&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;relwidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visually jarring when values change significantly (e.g., 20% → 75%).&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.amazonaws.com%2Fuploads%2Farticles%2Fiqu6jhfvkon2hf97sooh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqu6jhfvkon2hf97sooh.gif" alt=" " width="599" height="313"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Solution: Ease-out Animation Component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ui/components/led_bars.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AnimatedBar&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;__init__&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;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&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;bg_frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#1e293b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;height&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;_fill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Frame&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;bg_frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;height&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;_fill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;place&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;relx&lt;/span&gt;&lt;span class="o"&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;rely&lt;/span&gt;&lt;span class="o"&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;relwidth&lt;/span&gt;&lt;span class="o"&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;relheight&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;_current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&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;_target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&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;_animating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_target&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;pct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Set target percentage (0.0 to 1.0)&lt;/span&gt;&lt;span class="sh"&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;_target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&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="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pct&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_animating&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;_animating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&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;_step&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;_step&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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Animation frame (ease-out)&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;diff&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;_target&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;_current&lt;/span&gt;

        &lt;span class="c1"&gt;# Snap threshold: 0.4%
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.004&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;_current&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;_target&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;_fill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;place&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;relwidth&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;_current&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;_animating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="c1"&gt;# Ease factor: 18% of gap per frame
&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&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.18&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;_fill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;place&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;relwidth&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;_current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# ~60fps
&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;_fill&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;16&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;_step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Design Choices
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;th&gt;Reasoning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ease-out vs fixed-step&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Always converges, no oscillation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Snap threshold (0.4%)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prevents infinite micro-adjustments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;18% ease factor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fast initial movement, smooth slow-down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;16ms frame time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~60fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Layout-agnostic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;bg_frame&lt;/code&gt; packs/grids anywhere&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Session Averages (3 bars)
&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;cpu_bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AnimatedBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#3b82f6&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;cpu_bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bg_frame&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="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pady&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&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;cpu_bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.63&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 63%
&lt;/span&gt;
&lt;span class="c1"&gt;# TOP 5 Processes (10 bars × 2 panels = 20 instances)
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;cpu_bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AnimatedBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row_frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#3b82f6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ram_bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AnimatedBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row_frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#fbbf24&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ... layout logic
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; All bars in app use same component. Future bars = 2 lines of code.&lt;/p&gt;
&lt;/blockquote&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.amazonaws.com%2Fuploads%2Farticles%2Flwsams2oto9i43ugmwpk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwsams2oto9i43ugmwpk.gif" alt=" " width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Process Display Redesign
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Before (22px tall):
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. chrome.exe    [C ████░░ 12%] [R ██░░░░ 8%]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Issues:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single-char labels (&lt;code&gt;C&lt;/code&gt;, &lt;code&gt;R&lt;/code&gt;) unclear&lt;/li&gt;
&lt;li&gt;Name truncated at 14 chars (&lt;code&gt;EpicGamesLau...&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Cramped layout&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  After (36px tall):
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. chrome.exe
   CPU ████████░░ 12%   |   RAM ████░░░░ 35%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Changes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two-line layout&lt;/li&gt;
&lt;li&gt;Full labels (CPU, RAM) in accent colors&lt;/li&gt;
&lt;li&gt;Name limit: 20 chars (covers most processes)&lt;/li&gt;
&lt;li&gt;Equal-width bars with visual divider&lt;/li&gt;
&lt;li&gt;Better hierarchy (name bold, metrics secondary)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Row container
&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;panel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bg_panel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;row&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="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pady&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="c1"&gt;# Line 1: Process name
&lt;/span&gt;&lt;span class="n"&gt;name_label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;proc_name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;20&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;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bg_panel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;fg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;font&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;Consolas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;name_label&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="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pady&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&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="c1"&gt;# Line 2: Metrics container
&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bg_panel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;metrics&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="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pady&lt;/span&gt;&lt;span class="o"&gt;=&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# CPU half
&lt;/span&gt;&lt;span class="n"&gt;cpu_frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bg_panel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;cpu_frame&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="n"&gt;side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;both&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&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;cpu_label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpu_frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CPU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="n"&gt;fg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#3b82f6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font&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;Consolas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;cpu_label&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="n"&gt;side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cpu_bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AnimatedBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpu_frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#3b82f6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cpu_bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bg_frame&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="n"&gt;side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&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;padx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cpu_pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpu_frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&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;fg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;muted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;font&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;Consolas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;cpu_pct&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="n"&gt;side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;right&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Divider
&lt;/span&gt;&lt;span class="n"&gt;divider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;muted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;width&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;divider&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="n"&gt;side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# RAM half (same pattern)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Processes now identifiable at a glance. No guessing what &lt;code&gt;C&lt;/code&gt; and &lt;code&gt;R&lt;/code&gt; mean.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Chart Fixes: Three Bugs, One Session
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bug 1: Blank on Startup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; &lt;code&gt;canvas.winfo_width()&lt;/code&gt; returns &lt;code&gt;1&lt;/code&gt; before tkinter paints widget. Retry logic was fragile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&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="c1"&gt;# Canonical tkinter pattern for "wait for real dimensions"
&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;realtime_canvas&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;Configure&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_chart_configure&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;_on_chart_configure&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;event&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Fires when canvas gets real dimensions (or resizes)&lt;/span&gt;&lt;span class="sh"&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;_chart_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;# Reset item pool
&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;_schedule_chart_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Immediate redraw
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Chart renders on first paint, every time.&lt;/p&gt;




&lt;h3&gt;
  
  
  Bug 2: Filter Lag
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Clicking &lt;code&gt;1H&lt;/code&gt; or &lt;code&gt;4H&lt;/code&gt; loaded data but chart didn't update until next 2-second tick.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_on_filter_click&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;filter_name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;User clicked 1H, 4H, or Live&lt;/span&gt;&lt;span class="sh"&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;_current_filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter_name&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;_load_chart_data&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;_schedule_chart_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# ← Added this line
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Instant visual feedback on filter change.&lt;/p&gt;




&lt;h3&gt;
  
  
  Bug 3: Color Inconsistency
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Chart used &lt;code&gt;#1e3a8a&lt;/code&gt;, &lt;code&gt;#92400e&lt;/code&gt;, &lt;code&gt;#064e3b&lt;/code&gt; (dark navy, brown, dark green) — remnants from intermediate implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&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="c1"&gt;# Consistent palette used everywhere else in app
&lt;/span&gt;&lt;span class="n"&gt;CHART_COLORS&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;cpu&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;#3b82f6&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# Blue
&lt;/span&gt;    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ram&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;#fbbf24&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# Amber
&lt;/span&gt;    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gpu&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;#10b981&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;    &lt;span class="c1"&gt;# Green
&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;Result:&lt;/strong&gt; Visual consistency across entire interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Coming: TURBO Mode
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvbwaqryrpwfn1ssvv2y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvbwaqryrpwfn1ssvv2y.gif" alt=" " width="720" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 1.7.x series builds toward &lt;strong&gt;TURBO Mode&lt;/strong&gt; — Windows system optimization tools triggered from dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Planned Features
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Stop Non-Essential Services
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Pseudocode
&lt;/span&gt;&lt;span class="n"&gt;essential&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;Dhcp&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;Dnscache&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;EventLog&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;span class="n"&gt;running&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_running_services&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;stoppable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&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;essential&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;service&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stoppable&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;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cpu_avg_7d&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ram_avg_mb&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&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;Impact:&lt;/strong&gt; Free CPU/RAM from background services user doesn't need.&lt;/p&gt;




&lt;h4&gt;
  
  
  2. Unpark CPU Cores
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Windows parks cores under light load
# TURBO unpaks all physical cores
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cpu_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logical&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="nf"&gt;set_core_parked_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parked&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&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;Impact:&lt;/strong&gt; All cores available for compute-heavy tasks.&lt;/p&gt;




&lt;h4&gt;
  
  
  3. Auto Power Plan Switch
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Switch based on load threshold
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cpu_avg_5min&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;gpu_avg_5min&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;set_power_plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;High Performance&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="nf"&gt;set_power_plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Balanced&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;&lt;strong&gt;Impact:&lt;/strong&gt; Performance when needed, power saving when idle.&lt;/p&gt;




&lt;h4&gt;
  
  
  4. RAM Flush (&amp;gt;75% usage)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Clear Windows standby list
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ram_percent&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;flush_standby_list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# ctypes call to kernel32
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Reclaim cached RAM under memory pressure.&lt;/p&gt;




&lt;h4&gt;
  
  
  5. Suspend Inactive Processes
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Identify processes idle &amp;gt;10min
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;proc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;running_processes&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;proc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cpu_time_last_10min&lt;/span&gt; &lt;span class="o"&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;proc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;suspend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# psutil.Process.suspend()
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Free resources from backgrounded apps.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TURBO Mode touches Windows internals.&lt;/strong&gt; Incorrect implementation = system instability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Verified data pipeline (tests)&lt;/li&gt;
&lt;li&gt;Clean codebase (no dead code confusion)&lt;/li&gt;
&lt;li&gt;Stable UI components (AnimatedBar reusable)&lt;/li&gt;
&lt;li&gt;Bug-free monitoring (chart fixes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;v1.7.1 provides all of these.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When TURBO features land (1.7.2-1.7.8), they'll be built on solid foundation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scarred: Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Sleep debt is real
&lt;/h3&gt;

&lt;p&gt;Flow state at 6 AM on 5.5h sleep? Lucky. Not sustainable.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Foundation work is invisible
&lt;/h3&gt;

&lt;p&gt;No screenshots. No new features. But when TURBO Mode doesn't crash Windows? This is why.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Community feedback → credibility
&lt;/h3&gt;

&lt;p&gt;Mary-devz raised testing issue. I shipped tests. Issue closed. Trust built.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Flow state doesn't wait
&lt;/h3&gt;

&lt;p&gt;Best coding happens when it happens. 9h retail shift → 5.5h sleep → flow state → full release.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Plan around energy, not calendar.&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;&lt;strong&gt;1.7.2 scope (next week):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI button redesign (original roadmap item)&lt;/li&gt;
&lt;li&gt;Possibly auto-update check (#14 - quick win)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.7.x series:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TURBO Mode implementation (features listed above)&lt;/li&gt;
&lt;li&gt;Complete "My PC" health tab&lt;/li&gt;
&lt;li&gt;Microsoft Store preparation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Long-term:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;v1.7.8 feature-complete&lt;/li&gt;
&lt;li&gt;Store submission Q3 2026&lt;/li&gt;
&lt;li&gt;v2.0 with full TURBO suite&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Core&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python 3.8+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UI Framework&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PyQt6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Legacy UI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tkinter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;psutil&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SQLite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Testing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;unittest + unittest.mock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PyInstaller&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Signing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sigstore&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PC Workman v1.7.1:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK/releases/tag/v1.7.1" rel="noopener noreferrer"&gt;Release Notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK#readme" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK/releases/latest" rel="noopener noreferrer"&gt;Download Latest&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Follow development:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;X: &lt;a href="https://twitter.com/hck_lab" rel="noopener noreferrer"&gt;@hck_lab&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://linkedin.com/in/marcinfirmuga" rel="noopener noreferrer"&gt;Marcin Firmuga&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/huckler"&gt;@huckler&lt;/a&gt;
&lt;a href="https://ko-fi.com/hhlabs" rel="noopener noreferrer"&gt;COFFE? - And All Where I am :)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pxw2awrjdszgdw1l2tw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pxw2awrjdszgdw1l2tw.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Friday Shipped &amp;amp; Scarred continues next week.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marcin Firmuga (HCK_Labs)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Building PC Workman in public. One release at a time.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Monday Grind Blueprint #2: 80 Processes Explained, 3 Issues Targeted, 1 Week to Ship</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Mon, 06 Apr 2026 22:05:17 +0000</pubDate>
      <link>https://dev.to/huckler/monday-grind-blueprint-2-80-processes-explained-3-issues-targeted-1-week-to-ship-785</link>
      <guid>https://dev.to/huckler/monday-grind-blueprint-2-80-processes-explained-3-issues-targeted-1-week-to-ship-785</guid>
      <description>&lt;h3&gt;
  
  
  Nobody needs another AI feature.
&lt;/h3&gt;

&lt;p&gt;They need to know if svchost.exe is safe or a virus.&lt;br&gt;
I spent Easter weekend building something embarrassingly simple: a JSON file that explains what 80+ Windows processes actually do.&lt;br&gt;
Not machine learning. Not blockchain integration. Not "AI-powered insights."&lt;br&gt;
Just context.&lt;br&gt;
And it works better than I expected.&lt;/p&gt;

&lt;p&gt;The Problem: Task Manager Shows Data, Not Understanding&lt;br&gt;
Open Task Manager right now. You'll see:&lt;/p&gt;

&lt;p&gt;svchost.exe — 6 instances, 800MB RAM&lt;br&gt;
dwm.exe — 40% CPU spike&lt;br&gt;
RuntimeBroker.exe — Random activity&lt;br&gt;
System — Always at the top&lt;/p&gt;

&lt;p&gt;What do you do?&lt;br&gt;
Google "is svchost.exe a virus?"&lt;br&gt;
Read 10 forum threads.&lt;br&gt;
Still not sure.&lt;br&gt;
Maybe kill the process.&lt;br&gt;
Break something.&lt;br&gt;
PC_Workman now solves this in 0.5 seconds:&lt;br&gt;
Hover on svchost.exe in the chat →&lt;br&gt;
Service Host Process&lt;br&gt;
Microsoft Corporation&lt;br&gt;
Hosts Windows services. Multiple instances are normal.&lt;br&gt;
Power: Low-Medium&lt;br&gt;
Safety: Safe (part of Windows)&lt;br&gt;
CPU: 1-15% per instance&lt;br&gt;
RAM: 50-200MB per instance&lt;br&gt;
Done.&lt;br&gt;
No Google. No paranoia. Just facts.&lt;/p&gt;

&lt;p&gt;Easter Weekend: From "Too Tired" to "Shipped"&lt;br&gt;
Context:&lt;br&gt;
Week 1 at Żabka retail: 5:30 AM starts, solo store shifts by day 5, 20 zł/h (~$5/hour).&lt;br&gt;
Monday plan: Process library + timestamps + 2 articles&lt;br&gt;
Tuesday-Friday reality: Too exhausted to code after 9-hour shifts&lt;br&gt;
Saturday-Sunday: Redemption arc&lt;br&gt;
What shipped:&lt;/p&gt;

&lt;p&gt;process_library.json — 80+ process definitions&lt;br&gt;
process_library.py — Loader with lookups&lt;br&gt;
tooltip.py — Hover UI widget&lt;br&gt;
Integration in panel.py — Regex binding for chat&lt;/p&gt;

&lt;p&gt;Time: ~4 hours total&lt;br&gt;
Difficulty: Medium (Tkinter events + regex)&lt;br&gt;
Impact: HIGH (users finally understand what processes are)&lt;/p&gt;

&lt;p&gt;What I Built: The Process Library System&lt;br&gt;
File 1: process_library.json (The Data)&lt;br&gt;
Location: PC_Workman_HCK/data/process_library.json&lt;br&gt;
Size: 80+ definitions (will grow to 150+)&lt;br&gt;
Categories:&lt;/p&gt;

&lt;p&gt;System: explorer.exe, svchost.exe, dwm.exe, csrss.exe&lt;br&gt;
Browsers: chrome.exe, firefox.exe, edge.exe, opera.exe, brave.exe&lt;br&gt;
Gaming: steam.exe, valorant.exe, leagueoflegends.exe, fortnite.exe, minecraft.exe&lt;br&gt;
Development: python.exe, node.exe, code.exe, docker.exe, git.exe&lt;br&gt;
Communication: discord.exe, teams.exe, zoom.exe, slack.exe&lt;br&gt;
Media: spotify.exe, vlc.exe, obs64.exe, photoshop.exe&lt;br&gt;
Productivity: excel.exe, word.exe, notion.exe, outlook.exe&lt;br&gt;
Utilities: 7zfm.exe, winrar.exe, everything.exe&lt;br&gt;
Virtualization: vmware.exe, virtualbox.exe&lt;/p&gt;

&lt;p&gt;Structure:&lt;br&gt;
&lt;code&gt;json{&lt;br&gt;
  "chrome.exe": {&lt;br&gt;
    "name": "Google Chrome",&lt;br&gt;
    "vendor": "Google LLC",&lt;br&gt;
    "category": "browser",&lt;br&gt;
    "description": "Web browser. RAM usage increases with open tabs.",&lt;br&gt;
    "power_usage": "high",&lt;br&gt;
    "safety": "safe",&lt;br&gt;
    "typical_cpu": "5-25%",&lt;br&gt;
    "typical_ram": "200-800MB per window"&lt;br&gt;
  },&lt;br&gt;
  "svchost.exe": {&lt;br&gt;
    "name": "Service Host Process",&lt;br&gt;
    "vendor": "Microsoft Corporation",&lt;br&gt;
    "category": "system",&lt;br&gt;
    "description": "Hosts Windows services. Multiple instances are normal.",&lt;br&gt;
    "power_usage": "low_medium",&lt;br&gt;
    "safety": "safe",&lt;br&gt;
    "typical_cpu": "1-15% per instance",&lt;br&gt;
    "typical_ram": "50-200MB per instance"&lt;br&gt;
  }&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
No AI-generated descriptions. All written in plain English, human-verified.&lt;/p&gt;

&lt;p&gt;File 2: process_library.py (The Loader)&lt;br&gt;
Location: PC_Workman_HCK/hck_gpt/process_library.py&lt;br&gt;
What it does:&lt;/p&gt;

&lt;p&gt;Loads JSON on startup&lt;br&gt;
Provides case-insensitive lookups&lt;br&gt;
Formats tooltip text for display&lt;/p&gt;

&lt;p&gt;Implementation:&lt;br&gt;
pythonclass ProcessLibrary:&lt;br&gt;
`    """Loads process definitions from JSON and provides lookups"""&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def __init__(self):
    self.processes = {}
    self._load_library()

def _load_library(self):
    """Load process_library.json"""
    lib_path = os.path.join(
        os.path.dirname(__file__), 
        '..', 
        'data', 
        'process_library.json'
    )

    if os.path.exists(lib_path):
        with open(lib_path, 'r', encoding='utf-8') as f:
            self.processes = json.load(f)
        print(f"[ProcessLibrary] Loaded {len(self.processes)} process definitions")

def get_process_info(self, process_name):
    """Case-insensitive lookup"""
    return self.processes.get(process_name.lower().strip())

def format_tooltip_text(self, process_name):
    """Format for display"""
    info = self.get_process_info(process_name)
    if not info:
        return None

    return f"""📦 {info['name']}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;{info['vendor']}&lt;/p&gt;

&lt;p&gt;{info['description']}&lt;/p&gt;

&lt;p&gt;Power: {info['power_usage']}&lt;br&gt;
Safety: {info['safety']}&lt;br&gt;
CPU: {info['typical_cpu']}&lt;br&gt;
RAM: {info['typical_ram']}"""&lt;/p&gt;
&lt;h1&gt;
  
  
  Singleton instance
&lt;/h1&gt;

&lt;p&gt;process_library = ProcessLibrary()`&lt;br&gt;
Why singleton? One load at startup, shared across all components.&lt;/p&gt;

&lt;p&gt;File 3: tooltip.py (The UI Widget)&lt;br&gt;
Location: PC_Workman_HCK/hck_gpt/tooltip.py&lt;br&gt;
What it does:&lt;/p&gt;

&lt;p&gt;Creates borderless tooltip window&lt;br&gt;
Positions near mouse cursor&lt;br&gt;
Displays formatted process information&lt;br&gt;
Auto-hides on mouse leave&lt;/p&gt;

&lt;p&gt;Implementation:&lt;br&gt;
pythonclass ProcessTooltip:&lt;br&gt;
`    """Shows tooltip on hover over process names"""&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def __init__(self, parent):
    self.parent = parent
    self.tooltip_window = None

def show(self, event, process_name, tooltip_text):
    """Show tooltip at mouse position"""
    if not tooltip_text:
        return

    self.hide()  # Destroy old tooltip

    # Create borderless window
    self.tooltip_window = tk.Toplevel(self.parent)
    self.tooltip_window.wm_overrideredirect(True)
    self.tooltip_window.wm_attributes("-topmost", True)

    # Position near mouse
    x = event.x_root + 20
    y = event.y_root + 10
    self.tooltip_window.wm_geometry(f"+{x}+{y}")

    # Styled frame + label
    frame = tk.Frame(
        self.tooltip_window,
        bg=THEME["bg_panel"],
        highlightbackground=THEME["accent2"],
        highlightthickness=2,
        padx=12,
        pady=8
    )
    frame.pack()

    label = tk.Label(
        frame,
        text=tooltip_text,
        bg=THEME["bg_panel"],
        fg=THEME["text"],
        font=("Consolas", 9),
        justify="left"
    )
    label.pack()

def hide(self):
    """Destroy tooltip"""
    if self.tooltip_window:
        self.tooltip_window.destroy()
        self.tooltip_window = None`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Positioning logic: +20px right, +10px down from cursor to avoid blocking text.&lt;/p&gt;

&lt;p&gt;File 4: panel.py (The Integration)&lt;br&gt;
Location: PC_Workman_HCK/hck_gpt/panel.py&lt;br&gt;
What changed:&lt;/p&gt;

&lt;p&gt;Import process library:&lt;br&gt;
`&lt;br&gt;
pythonimport re&lt;/p&gt;

&lt;p&gt;try:&lt;br&gt;
    from hck_gpt.process_library import process_library&lt;br&gt;
    from hck_gpt.tooltip import ProcessTooltip&lt;br&gt;
    HAS_PROCESS_LIBRARY = True&lt;br&gt;
except ImportError:&lt;br&gt;
    HAS_PROCESS_LIBRARY = False&lt;br&gt;
    print("[hck_GPT] Process library not available")&lt;/p&gt;

&lt;p&gt;Initialize tooltip in &lt;strong&gt;init&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;python# Tooltip system&lt;br&gt;
self.tooltip = ProcessTooltip(parent) if HAS_PROCESS_LIBRARY else None&lt;/p&gt;

&lt;p&gt;Bind tooltips method:&lt;/p&gt;

&lt;p&gt;pythondef _bind_process_tooltips(self):&lt;br&gt;
    """Scan chat text for process names and bind hover events"""&lt;br&gt;
    if not HAS_PROCESS_LIBRARY or not self.tooltip:&lt;br&gt;
        return&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Get all text
content = self.log.get("1.0", "end-1c")

# Search for .exe patterns
exe_pattern = r'\b\w+\.exe\b'

for match in re.finditer(exe_pattern, content, re.IGNORECASE):
    process_name = match.group(0)

    # Check if process exists in library
    info = process_library.get_process_info(process_name)

    if info:
        # Create unique tag
        tag_name = f"process_{process_name}_{match.start()}"

        # Add tag to text
        # (Tkinter text index conversion logic here)
        self.log.tag_add(tag_name, start_pos, end_pos)

        # Style the tag (underline, color)
        self.log.tag_config(
            tag_name,
            foreground=THEME["accent2"],
            underline=True
        )

        # Bind hover events
        tooltip_text = process_library.format_tooltip_text(process_name)

        self.log.tag_bind(
            tag_name,
            "&amp;lt;Enter&amp;gt;",
            lambda e, pn=process_name, tt=tooltip_text: 
                self.tooltip.show(e, pn, tt)
        )

        self.log.tag_bind(
            tag_name,
            "&amp;lt;Leave&amp;gt;",
            lambda e: self.tooltip.hide()
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Call after adding messages:&lt;/p&gt;

&lt;p&gt;pythondef add_message(self, msg):&lt;br&gt;
    # ... add text to chat&lt;br&gt;
    self._bind_process_tooltips()  # Scan and bind`&lt;br&gt;
Regex pattern: r'\b\w+.exe\b' matches word boundaries + .exe extension (case-insensitive)&lt;br&gt;
Why unique tags? Same process can appear multiple times in chat — each occurrence needs separate hover binding.&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.amazonaws.com%2Fuploads%2Farticles%2Fy1jcqd21nc0mwrfcdvo3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1jcqd21nc0mwrfcdvo3.gif" alt=" " width="720" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why This Matters&lt;br&gt;
Before process library:&lt;br&gt;
User: "epicgames.exe is using 40% CPU — is that normal?"&lt;br&gt;
Action: Google → Reddit → forum threads → paranoia → maybe kill process&lt;br&gt;
After process library:&lt;br&gt;
User hovers on epicgames.exe&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Epic Games Launcher
Epic Games, Inc.
Game distribution platform. Updates games in background.
Power: Medium-High
Safety: Safe
CPU: 10-40% (during updates)
RAM: 300-800MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;User: "Oh, it's updating games. That's fine."&lt;br&gt;
Result: Informed decision instead of guessing.&lt;/p&gt;

&lt;p&gt;This Week's Plan: 3 Issues from Roadmap 1.7.8&lt;br&gt;
Full roadmap: &lt;a href="https://github.com/users/HuckleR2003/projects/3/views/2?pane=issue&amp;amp;itemId=166508113&amp;amp;issue=HuckleR2003%7CPC_Workman_HCK%7C17" rel="noopener noreferrer"&gt;https://github.com/users/HuckleR2003/projects/3/views/2?pane=issue&amp;amp;itemId=166508113&amp;amp;issue=HuckleR2003%7CPC_Workman_HCK%7C17&lt;/a&gt;&lt;br&gt;
Total issues to v1.7.8: 17&lt;br&gt;
Selected for this week: 3&lt;/p&gt;

&lt;p&gt;Issue #1: Missing tests, discussions, packaging&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.amazonaws.com%2Fuploads%2Farticles%2F898fwsboi2e5vprq50d0.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.amazonaws.com%2Fuploads%2Farticles%2F898fwsboi2e5vprq50d0.png" alt=" " width="800" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: GitHub issue from Mary-devz (community feedback)&lt;br&gt;
Problem:&lt;/p&gt;

&lt;p&gt;No automated tests yet&lt;br&gt;
Need discussion about update mechanisms&lt;br&gt;
Packaging strategy unclear&lt;/p&gt;

&lt;p&gt;Plan:&lt;/p&gt;

&lt;p&gt;Set up pytest framework&lt;br&gt;
Create test suite for core modules&lt;br&gt;
Discuss auto-update vs manual download strategy&lt;br&gt;
Define packaging requirements for Microsoft Store&lt;/p&gt;

&lt;p&gt;Why this matters: Community feedback = roadmap priorities&lt;/p&gt;

&lt;p&gt;Issue #2: [UI] Main dashboard button graphics redesign&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.amazonaws.com%2Fuploads%2Farticles%2Fhl26mjgg5ycf2mxlc1a9.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.amazonaws.com%2Fuploads%2Farticles%2Fhl26mjgg5ycf2mxlc1a9.png" alt=" " width="800" height="47"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: Own issue&lt;br&gt;
Problem:&lt;/p&gt;

&lt;p&gt;Current buttons functional but inconsistent&lt;br&gt;
Need final visual style before Store submission&lt;br&gt;
Button states (normal/hover/active) need polish&lt;/p&gt;

&lt;p&gt;Plan:&lt;/p&gt;

&lt;p&gt;Finalize button style guide&lt;br&gt;
Redesign primary controls (Start Monitoring, Settings, Reports)&lt;br&gt;
Implement hover animations&lt;br&gt;
Ensure accessibility (contrast ratios, click targets)&lt;/p&gt;

&lt;p&gt;Why this matters: UI = first impression for new users&lt;/p&gt;

&lt;p&gt;Issue #3: [Code] Optimize hck_gpt/ modules&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.amazonaws.com%2Fuploads%2Farticles%2Fqrv6wa2xdqwqidcp9x75.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.amazonaws.com%2Fuploads%2Farticles%2Fqrv6wa2xdqwqidcp9x75.png" alt=" " width="800" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: Own issue&lt;br&gt;
Problem:&lt;/p&gt;

&lt;p&gt;Multiple small files in hck_gpt/ folder&lt;br&gt;
Some code duplication&lt;br&gt;
Performance could be better&lt;/p&gt;

&lt;p&gt;Plan:&lt;/p&gt;

&lt;p&gt;Analyze module dependencies&lt;br&gt;
Consolidate related functionality&lt;br&gt;
Remove duplicate code&lt;br&gt;
Profile performance bottlenecks&lt;br&gt;
Document optimization decisions&lt;/p&gt;

&lt;p&gt;Why this matters: Clean code = easier maintenance = faster feature development&lt;/p&gt;

&lt;p&gt;Build-in-Public Philosophy&lt;br&gt;
Why share the struggle?&lt;br&gt;
Because "I planned X, did Y" is more valuable than "look at my perfect progress."&lt;br&gt;
Week 1 reality:&lt;/p&gt;

&lt;p&gt;Monday: Ambitious plan&lt;br&gt;
Tuesday-Friday: Too tired after Żabka&lt;br&gt;
Saturday-Sunday: Catch-up sprint&lt;br&gt;
Monday: Selective focus on 3 issues&lt;/p&gt;

&lt;p&gt;Not shipping everything. Shipping what matters.&lt;br&gt;
The gap between plan and execution = the actual content.&lt;/p&gt;

&lt;p&gt;Current State &amp;amp; Goals&lt;br&gt;
Today:&lt;/p&gt;

&lt;p&gt;Day job: Żabka retail (20 zł/h, 1-2 months bridge)&lt;br&gt;
Dev time: Weekends + evenings when possible&lt;br&gt;
PC_Workman: v1.7.0 (process library shipped)&lt;/p&gt;

&lt;p&gt;This week:&lt;/p&gt;

&lt;p&gt;Close 3 issues from roadmap&lt;br&gt;
Build momentum toward v1.7.8&lt;/p&gt;

&lt;p&gt;April target:&lt;/p&gt;

&lt;p&gt;v1.7.8 feature-complete&lt;br&gt;
All critical issues resolved&lt;/p&gt;

&lt;p&gt;Q3 2026:&lt;/p&gt;

&lt;p&gt;Microsoft Store submission&lt;br&gt;
Public release v2.0&lt;/p&gt;

&lt;p&gt;June-July 2026:&lt;/p&gt;

&lt;p&gt;Exit Żabka → Junior dev role&lt;/p&gt;

&lt;p&gt;What's Next&lt;br&gt;
Process library expansion:&lt;/p&gt;

&lt;p&gt;Target: 150+ definitions by v1.7.8&lt;br&gt;
Community contributions (submit PRs with process definitions)&lt;br&gt;
Auto-categorization for unknown processes (future)&lt;/p&gt;

&lt;p&gt;This week deliverables:&lt;/p&gt;

&lt;p&gt;Test framework setup + initial tests&lt;br&gt;
UI button redesign completed&lt;br&gt;
hck_gpt/ optimization documented&lt;/p&gt;

&lt;p&gt;Long-term vision:&lt;/p&gt;

&lt;p&gt;Microsoft Store release&lt;br&gt;
Cross-platform support (Linux, macOS)&lt;br&gt;
Process behavior learning (detect unusual patterns)&lt;/p&gt;

&lt;p&gt;Try It Yourself&lt;br&gt;
PC_Workman v1.7.0:&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;https://github.com/HuckleR2003/PC_Workman_HCK&lt;/a&gt;&lt;br&gt;
Free, open source, portable .exe&lt;br&gt;
Windows 10/11&lt;/p&gt;

&lt;p&gt;Process library:&lt;/p&gt;

&lt;p&gt;JSON format (easy to extend)&lt;br&gt;
MIT license&lt;br&gt;
Contributions welcome&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.amazonaws.com%2Fuploads%2Farticles%2Frxn9ppboqqbvgp0ma3l0.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.amazonaws.com%2Fuploads%2Farticles%2Frxn9ppboqqbvgp0ma3l0.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, here :)&lt;br&gt;
&lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;All my links here :)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About the Author&lt;br&gt;
I’m Marcin Firmuga. Solo developer and founder of HCK_Labs.&lt;/p&gt;

&lt;p&gt;I created PC Workman , an open-source, AI-powered&lt;br&gt;
PC resource monitor&lt;br&gt;
built entirely from scratch on dying hardware during warehouse&lt;br&gt;
shifts in the Netherlands.&lt;br&gt;
This is the first time I’ve given one of my projects a real, dedicated home.&lt;/p&gt;

&lt;p&gt;Before this: game translations, PC technician internships, warehouse operations in multiple countries, and countless failed projects I never finished.&lt;/p&gt;

&lt;p&gt;But this one? This one stuck.&lt;br&gt;
800+ hours of code. 4 complete UI rebuilds. 16,000 lines deleted.&lt;br&gt;
3 AM all-nighters. Energy drinks and toast.&lt;/p&gt;

&lt;p&gt;And finally, an app I wouldn’t close in 5 seconds.&lt;br&gt;
That’s the difference between building and shipping.&lt;/p&gt;

&lt;p&gt;PC_Workman is the result.&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>buildinpublic</category>
      <category>devops</category>
    </item>
    <item>
      <title>Friday Shipped &amp; Scarred #1: The Day git --force Deleted 130 PC Workman Commits (I Got 90 Back)</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Fri, 27 Mar 2026 13:03:34 +0000</pubDate>
      <link>https://dev.to/huckler/friday-shipped-scarred-1-the-day-git-force-deleted-130-pc-workman-commits-i-got-90-back-1947</link>
      <guid>https://dev.to/huckler/friday-shipped-scarred-1-the-day-git-force-deleted-130-pc-workman-commits-i-got-90-back-1947</guid>
      <description>&lt;h1&gt;
  
  
  Friday Shipped &amp;amp; Scarred #1: The Day git --force Deleted 130 Commits (And How I Got 90 Back)
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;First in a weekly series tracking PC_Workman development. The good, the broken, the lessons learned.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Monday: My Heart Stopped
&lt;/h2&gt;

&lt;p&gt;I ran &lt;code&gt;git push --force&lt;/code&gt; on PC_Workman.&lt;br&gt;
130 commits became 1 commit.&lt;/p&gt;

&lt;p&gt;Eight months of development history disappeared.&lt;br&gt;
Not the code. The code was fine. But the &lt;strong&gt;story&lt;/strong&gt; was gone.&lt;/p&gt;

&lt;p&gt;Every "Fixed memory leak" commit. Every "Rebuilt UI (again)" message. Every timestamp proving this project wasn't slapped together over a weekend.&lt;br&gt;
Gone.&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.amazonaws.com%2Fuploads%2Farticles%2F8thxnyxvdo253iip18dg.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.amazonaws.com%2Fuploads%2Farticles%2F8thxnyxvdo253iip18dg.png" alt=" " width="800" height="159"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Panic
&lt;/h2&gt;

&lt;p&gt;First reaction: freeze.&lt;br&gt;
Second reaction: check GitHub.&lt;/p&gt;

&lt;p&gt;One commit. Master branch. That's it.&lt;br&gt;
&lt;strong&gt;Reflog?&lt;/strong&gt; Empty.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Old branches?&lt;/strong&gt; None with the history.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;GitHub API endpoints?&lt;/strong&gt; Nothing recoverable.&lt;/p&gt;

&lt;p&gt;I'd read about this happening to others. "Always backup before git surgery" they said.&lt;br&gt;
I didn't backup this time...&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.amazonaws.com%2Fuploads%2Farticles%2Fx03cw8486g6k0hn3viys.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.amazonaws.com%2Fuploads%2Farticles%2Fx03cw8486g6k0hn3viys.png" alt=" " width="800" height="132"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Recovery: An Accidental Save
&lt;/h2&gt;

&lt;p&gt;Then I remembered something.&lt;/p&gt;

&lt;p&gt;Three weeks ago, I created an &lt;code&gt;archive&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;Not for backup. Just to keep old files around for reference. Old UI screenshots. Deprecated features. That kind of thing.&lt;/p&gt;

&lt;p&gt;I checked it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;90 commits.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not the full 130. But 90 commits with complete history dating back months.&lt;/p&gt;

&lt;p&gt;The archive had saved me.&lt;/p&gt;


&lt;h2&gt;
  
  
  What I Lost (And What I Kept)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lost:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;40 commits (most recent work)&lt;/li&gt;
&lt;li&gt;Detailed messages about recent bugfixes&lt;/li&gt;
&lt;li&gt;Exact timeline of last month's changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Kept:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;90 commits showing project evolution&lt;/li&gt;
&lt;li&gt;Proof of 8 months of development&lt;/li&gt;
&lt;li&gt;Complete rebuild history (I did 4 complete UI rebuilds - that's documented)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Could have lost:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;90 out of 130 = 69% recovery rate.&lt;/p&gt;

&lt;p&gt;Not perfect. But infinitely better than 1 out of 130.&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.amazonaws.com%2Fuploads%2Farticles%2Fc05kiexe2yns1svnly8i.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.amazonaws.com%2Fuploads%2Farticles%2Fc05kiexe2yns1svnly8i.png" alt=" " width="800" height="733"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  This Week: Cleaning Up What The Disaster Exposed
&lt;/h2&gt;

&lt;p&gt;The git crisis had a silver lining: it forced me to look closely at the repository.&lt;/p&gt;

&lt;p&gt;And I found... problems.&lt;/p&gt;
&lt;h3&gt;
  
  
  Problem 1: Missing CONTRIBUTING.md
&lt;/h3&gt;

&lt;p&gt;Someone opened an issue: "CONTRIBUTING.md link is broken"&lt;br&gt;
I checked. The file was gone.&lt;br&gt;
Lost in the git chaos. Never recovered from the archive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Rewrote it from scratch. Better this time. Clearer guidelines. Actual examples.&lt;br&gt;
&lt;strong&gt;Result:&lt;/strong&gt; Contributor can now actually contribute.&lt;/p&gt;


&lt;h3&gt;
  
  
  Problem 2: AI-Generated Patterns in README
&lt;/h3&gt;

&lt;p&gt;Last week I posted on Reddit asking why my project looked "AI-generated."&lt;br&gt;
Got brutal, honest feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Empty bullet points (&lt;code&gt;-&lt;/code&gt; with no text)&lt;/li&gt;
&lt;li&gt;Emoji bullets (everywhere)&lt;/li&gt;
&lt;li&gt;AI-style phrasing ("Why it's different" with arrow format)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removed all empty bullets&lt;/li&gt;
&lt;li&gt;Removed emoji formatting
&lt;/li&gt;
&lt;li&gt;Rewrote descriptions in plain English&lt;/li&gt;
&lt;li&gt;Added actual technical depth from CHANGELOG&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitors your PC&lt;/li&gt;
&lt;li&gt;Shows graphs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
Real-time CPU, GPU, RAM tracking with historical analysis.&lt;br&gt;
Dashboard loads optimized from 800ms to 200ms through widget reuse pattern.&lt;/p&gt;

&lt;p&gt;Specific. Technical. No fluff.&lt;/p&gt;


&lt;h3&gt;
  
  
  Problem 3: Polish UI Text (In An English Project)
&lt;/h3&gt;

&lt;p&gt;I thought I'd translated everything.&lt;br&gt;
I was wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Found Polish text in:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status messages ("Ładowanie..." = "Loading...")&lt;/li&gt;
&lt;li&gt;Dashboard labels ("Użycie CPU" = "CPU Usage")
&lt;/li&gt;
&lt;li&gt;Error messages&lt;/li&gt;
&lt;li&gt;Placeholder tooltips&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Files changed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ui/windows/main_window.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui/windows/main_window_expanded.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui/components/fan_dashboard.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui/components/sidebar_nav.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui/pages/fan_control/usage_stats.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui/pages/fan_control/hardware_info.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;6 more files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Time spent:&lt;/strong&gt; 6 hours&lt;br&gt;
&lt;strong&gt;Times I thought I was done:&lt;/strong&gt; 3&lt;br&gt;
&lt;strong&gt;Times I actually was done:&lt;/strong&gt; 1&lt;/p&gt;


&lt;h3&gt;
  
  
  Problem 4: Marketing Docstrings
&lt;/h3&gt;

&lt;p&gt;Early code had docstrings like:&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;update_dashboard&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Revolutionary real-time dashboard update system.
    Leverages advanced widget reuse patterns for optimal performance.
    Seamlessly integrates with monitoring engine.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# ... actual code
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nobody talks like this in real code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After cleanup:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update_dashboard&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Update dashboard widgets. Reuses existing widgets instead of recreating.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# ... actual code
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boring. Accurate. Better.&lt;/p&gt;

&lt;p&gt;Removed from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Main window files&lt;/li&gt;
&lt;li&gt;Fan dashboard&lt;/li&gt;
&lt;li&gt;All page components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Code reads like code, not a sales pitch.&lt;/p&gt;




&lt;h3&gt;
  
  
  Problem 5: Guide-AI Repository (Side Project)
&lt;/h3&gt;

&lt;p&gt;While cleaning PC_Workman, noticed Guide-AI repo was stale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No screenshots (people can't see what it does)&lt;/li&gt;
&lt;li&gt;No tags&lt;/li&gt;
&lt;li&gt;Outdated description&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fixed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added QR code demo screenshots&lt;/li&gt;
&lt;li&gt;Added proper GitHub topics (react, supabase, ai, qr-codes)&lt;/li&gt;
&lt;li&gt;Rewrote description with actual value prop
Not perfect. But visible now.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Shipped This Week
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Repository cleanup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CONTRIBUTING.md rewritten&lt;/li&gt;
&lt;li&gt;README cleanup&lt;/li&gt;
&lt;li&gt;12 files Polish -&amp;gt; English translation&lt;/li&gt;
&lt;li&gt;Marketing docstrings -&amp;gt; technical docstrings&lt;/li&gt;
&lt;li&gt;Guide-AI repo updated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;90+ commits recovered and visible&lt;/li&gt;
&lt;li&gt;0 empty bullet points remaining&lt;/li&gt;
&lt;li&gt;0 Polish UI strings remaining
&lt;/li&gt;
&lt;li&gt;0 "leverages advanced" phrases remaining&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Broke
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Git recovery wasn't perfect:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lost 40 commits&lt;/li&gt;
&lt;li&gt;Lost detailed timeline of February changes&lt;/li&gt;
&lt;li&gt;Had to manually recreate some documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Translation took 3x longer than expected:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Found Polish text in 12 files (thought it was 4)&lt;/li&gt;
&lt;li&gt;Each pass found more hidden strings&lt;/li&gt;
&lt;li&gt;Final check: found 3 more files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Time management:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Planned: 2 hours for cleanup&lt;/li&gt;
&lt;li&gt;Actual: 8 hours across 3 days&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Before ANY risky git operation:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch backup-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 seconds. Could save months.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. "Clean" code has layers
&lt;/h3&gt;

&lt;p&gt;First pass: obvious issues&lt;br&gt;&lt;br&gt;
Second pass: hidden patterns&lt;br&gt;&lt;br&gt;
Third pass: still finding things&lt;/p&gt;

&lt;p&gt;Clean once isn't enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Accidental backups count as backups
&lt;/h3&gt;

&lt;p&gt;That &lt;code&gt;archive&lt;/code&gt; branch saved me.&lt;br&gt;
Wasn't intentional. Still worked.&lt;br&gt;
Lesson: Keep old branches longer than you think necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Reddit feedback hurts but helps
&lt;/h3&gt;

&lt;p&gt;Being told your project "looks AI-generated" stings.&lt;br&gt;
But it pushed me to actually clean up the issues.&lt;br&gt;
Feedback &amp;lt;3.&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.amazonaws.com%2Fuploads%2Farticles%2Fiuom6r3qa5vrwjmd2h0k.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.amazonaws.com%2Fuploads%2Farticles%2Fiuom6r3qa5vrwjmd2h0k.png" alt=" " width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Week:
&lt;/h2&gt;

&lt;p&gt;-Monday Blueprint Grind #1&lt;br&gt;
-Wednesday Code Autopsy #2&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topic:&lt;/strong&gt; Process aggregation - how PC_Workman tracks per-process CPU/RAM usage without destroying performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Format:&lt;/strong&gt; Technical deep-dive into &lt;code&gt;hck_stats_engine/process_aggregator.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also coming:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First YouTube Short (Code Autopsy video format)&lt;/li&gt;
&lt;li&gt;v1.7.0 planning (TURBO mode research)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PC_Workman current state:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Version: 1.6.8&lt;/li&gt;
&lt;li&gt;Commits visible: 90+ (recovered)&lt;/li&gt;
&lt;li&gt;Development time: 800+ hours&lt;/li&gt;
&lt;li&gt;Next milestone: v2.0 → Microsoft Store (Q3 2026)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This week's time investment:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git recovery: 2 hours&lt;/li&gt;
&lt;li&gt;README cleanup: 1 hour
&lt;/li&gt;
&lt;li&gt;Code translation: 6 hours&lt;/li&gt;
&lt;li&gt;Documentation: 1 hour&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Total: 10 hours&lt;/strong&gt; (planned 4, actual 10)&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It / Break It / Fix It
&lt;/h2&gt;

&lt;p&gt;PC_Workman is open source. MIT licensed.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Download:&lt;/strong&gt; &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK/releases" rel="noopener noreferrer"&gt;Latest release&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Follow the journey:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;X: &lt;a href="https://x.com/hck_lab" rel="noopener noreferrer"&gt;@hck_lab&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://linkedin.com/in/marcinfirmuga" rel="noopener noreferrer"&gt;Marcin Firmuga&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Everything: &lt;a href="https://linktr.ee/marcin_firmuga" rel="noopener noreferrer"&gt;linktr.ee/marcin_firmuga&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Building in public. Shipped &amp;amp; Scarred every Friday.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questions, comments, roasts? Hit me up.&lt;/em&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.amazonaws.com%2Fuploads%2Farticles%2Facm4yq1cf2oj061ut53d.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.amazonaws.com%2Fuploads%2Farticles%2Facm4yq1cf2oj061ut53d.png" alt=" " width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About the Author
&lt;/h2&gt;

&lt;p&gt;I’m Marcin Firmuga. Solo developer and founder of HCK_Labs.&lt;/p&gt;

&lt;p&gt;I created PC Workman , an open-source, AI-powered&lt;br&gt;
PC resource monitor&lt;br&gt;
built entirely from scratch on dying hardware during warehouse&lt;br&gt;
shifts in the Netherlands.&lt;br&gt;
This is the first time I’ve given one of my projects a real, dedicated home.&lt;/p&gt;

&lt;p&gt;Before this: game translations, PC technician internships, warehouse operations in multiple countries, and countless failed projects I never finished.&lt;/p&gt;

&lt;p&gt;But this one? This one stuck.&lt;br&gt;
800+ hours of code. 4 complete UI rebuilds. 16,000 lines deleted.&lt;br&gt;
3 AM all-nighters. Energy drinks and toast.&lt;/p&gt;

&lt;p&gt;And finally, an app I wouldn’t close in 5 seconds.&lt;br&gt;
That’s the difference between building and shipping.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PC_Workman is the result.&lt;/p&gt;
&lt;/blockquote&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.amazonaws.com%2Fuploads%2Farticles%2Fhkivpgr2w38bq5fuzpum.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.amazonaws.com%2Fuploads%2Farticles%2Fhkivpgr2w38bq5fuzpum.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

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

&lt;/div&gt;

</description>
      <category>git</category>
      <category>buildinpublic</category>
      <category>opensource</category>
      <category>python</category>
    </item>
  </channel>
</rss>
