<?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.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>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; 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;
              Comments


              4&lt;span class="hidden s:inline"&gt; 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>
    <item>
      <title>My first series of Wednesday Code Autopsy!
Every wednesday :)</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Wed, 25 Mar 2026 20:23:34 +0000</pubDate>
      <link>https://dev.to/huckler/my-first-series-of-wednesday-code-autopsyevery-wednesday--348n</link>
      <guid>https://dev.to/huckler/my-first-series-of-wednesday-code-autopsyevery-wednesday--348n</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/huckler/code-autopsy-1-how-90-lines-turned-system-monitoring-into-a-conversation-2jh8" class="crayons-story__hidden-navigation-link"&gt;Code Autopsy #1: How ~90 Lines Turned System Monitoring Into A Conversation&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&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-3403990" 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/code-autopsy-1-how-90-lines-turned-system-monitoring-into-a-conversation-2jh8" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 25&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/code-autopsy-1-how-90-lines-turned-system-monitoring-into-a-conversation-2jh8" id="article-link-3403990"&gt;
          Code Autopsy #1: How ~90 Lines Turned System Monitoring Into A Conversation
        &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/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/buildinpublic"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;buildinpublic&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;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/huckler/code-autopsy-1-how-90-lines-turned-system-monitoring-into-a-conversation-2jh8" 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;35&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/huckler/code-autopsy-1-how-90-lines-turned-system-monitoring-into-a-conversation-2jh8#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&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;
            5 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>python</category>
      <category>opensource</category>
      <category>buildinpublic</category>
      <category>ai</category>
    </item>
    <item>
      <title>Code Autopsy #1: How ~90 Lines Turned System Monitoring Into A Conversation</title>
      <dc:creator>Marcin Firmuga</dc:creator>
      <pubDate>Wed, 25 Mar 2026 16:08:57 +0000</pubDate>
      <link>https://dev.to/huckler/code-autopsy-1-how-90-lines-turned-system-monitoring-into-a-conversation-2jh8</link>
      <guid>https://dev.to/huckler/code-autopsy-1-how-90-lines-turned-system-monitoring-into-a-conversation-2jh8</guid>
      <description>&lt;h1&gt;
  
  
  Code Autopsy #1: How 30 Lines Turned System Monitoring Into A Conversation
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Part of the PC_Workman build-in-public series. Code Autopsy drops every Wednesday.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Numbers Without Answers
&lt;/h2&gt;

&lt;p&gt;You open Task Manager.&lt;/p&gt;

&lt;p&gt;"CPU: 87%"&lt;/p&gt;

&lt;p&gt;Cool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But WHY 87%?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is that normal? Should you worry? What process caused it? When did it start?&lt;/p&gt;

&lt;p&gt;Task Manager doesn't answer. HWMonitor doesn't answer. MSI Afterburner doesn't answer.&lt;/p&gt;

&lt;p&gt;They show you WHAT is happening. Never WHY.&lt;/p&gt;

&lt;p&gt;That's the gap PC_Workman fills.&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%2Fljbtnzyq2zhtazorw48a.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%2Fljbtnzyq2zhtazorw48a.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PC Workman 1.6.8 - hck_GPT in action. Service Setup - quick access to disable useless services, or services what you don't will use (Bluetooth, Print, fax). Today Report - Info about correctly collecting data by sessions. Daily usage averages. And Alerts from suspected spikes/moments by temperatures or voltage.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Solution: EventDetector
&lt;/h2&gt;

&lt;p&gt;After 800 hours building PC_Workman (most of it on a laptop that peaks at 94°C), I realized: &lt;strong&gt;users don't need more data. They need context.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I built EventDetector.&lt;/p&gt;

&lt;p&gt;30 lines of Python that turn monitoring into a conversation.&lt;/p&gt;

&lt;p&gt;Here's how it works.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Track YOUR Baseline (Not Generic Averages)
&lt;/h2&gt;

&lt;p&gt;Most tools compare against hardcoded thresholds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"50% CPU is normal"&lt;/li&gt;
&lt;li&gt;"60% RAM is high"&lt;/li&gt;
&lt;li&gt;"80°C is warm"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Your normal isn't my normal.&lt;/p&gt;

&lt;p&gt;A gaming PC idling at 30% CPU? Normal.&lt;br&gt;&lt;br&gt;
A lightweight laptop idling at 30% CPU? Something's wrong.&lt;/p&gt;

&lt;p&gt;EventDetector tracks YOUR baseline from the last 10 minutes:&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_baseline&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;now&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Get recent baseline averages from minute_stats.
    Cached for 60 seconds to avoid excessive queries.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;cutoff&lt;/span&gt; &lt;span class="o"&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;SPIKE_BASELINE_WINDOW&lt;/span&gt;  &lt;span class="c1"&gt;# 10 minutes
&lt;/span&gt;
    &lt;span class="n"&gt;rows&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(cpu_avg) as cpu_avg, 
               AVG(ram_avg) as ram_avg,
               AVG(gpu_avg) as gpu_avg,
               AVG(cpu_temp) as cpu_temp, 
               AVG(gpu_temp) as gpu_temp
        FROM minute_stats
        WHERE timestamp &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;cutoff&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;baseline_cache&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt; The baseline is YOU. Not everyone. Just you.&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%2Fbg3li9zl2kem7yh5bxvl.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%2Fbg3li9zl2kem7yh5bxvl.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PC Workman 1.6.8 - Events detector for hck_GPT insights. Based on long-term monitoring: CPU, GPU, RAM. EventDetector code with highlights on baseline, delta, rate limiting, severity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Calculate Delta (Current vs YOUR Normal)
&lt;/h2&gt;

&lt;p&gt;Once we have YOUR baseline, detecting spikes is simple 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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_check_metric&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;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metric_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                  &lt;span class="n"&gt;baseline_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Check if a metric exceeds its threshold above baseline&lt;/span&gt;&lt;span class="sh"&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;current_val&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;baseline_val&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="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;  &lt;span class="c1"&gt;# No spike - you're within YOUR normal range
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Your CPU baseline (last 10 min): 42%&lt;/li&gt;
&lt;li&gt;Current CPU: 87%&lt;/li&gt;
&lt;li&gt;Delta: +45%&lt;/li&gt;
&lt;li&gt;Threshold: 20%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Spike detected. But we're not done yet.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Rate Limiting (No Alert Spam)
&lt;/h2&gt;

&lt;p&gt;Early versions of EventDetector had a problem: &lt;strong&gt;alert spam.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chrome spikes CPU every 30 seconds? You'd get 120 alerts per hour.&lt;/p&gt;

&lt;p&gt;Useless.&lt;/p&gt;

&lt;p&gt;Solution: Rate limiting.&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;# Rate limiting: {metric_name: last_event_timestamp}
&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_event_time&lt;/span&gt; &lt;span class="o"&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;_check_metric&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="p"&gt;...):&lt;/span&gt;
    &lt;span class="c1"&gt;# ... delta calculation ...
&lt;/span&gt;
    &lt;span class="c1"&gt;# Rate limiting
&lt;/span&gt;    &lt;span class="n"&gt;last_time&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_event_time&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;metric_name&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_time&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;SPIKE_COOLDOWN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# 5 minutes
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt;  &lt;span class="c1"&gt;# Too soon since last alert
&lt;/span&gt;
    &lt;span class="c1"&gt;# Log the event
&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_event_time&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;metric_name&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Max 1 alert per metric per 5 minutes. No spam.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Severity Levels (Critical vs Warning vs Info)
&lt;/h2&gt;

&lt;p&gt;Not all spikes are equal.&lt;/p&gt;

&lt;p&gt;CPU spiking 21% above baseline? Worth noting.&lt;br&gt;&lt;br&gt;
CPU spiking 60% above baseline? &lt;strong&gt;Drop everything.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EventDetector categorizes:&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;# Determine severity
&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="n"&gt;threshold&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;severity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;critical&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;  &lt;span class="c1"&gt;# 🔴
&lt;/span&gt;&lt;span class="k"&gt;elif&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="n"&gt;threshold&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;severity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;warning&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;   &lt;span class="c1"&gt;# ⚠️
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;severity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;info&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;      &lt;span class="c1"&gt;# ℹ️
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example thresholds:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU threshold: 20%&lt;/li&gt;
&lt;li&gt;Delta 40%+: Critical&lt;/li&gt;
&lt;li&gt;Delta 30%+: Warning&lt;/li&gt;
&lt;li&gt;Delta 20-29%: Info&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Alerts match urgency.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Final Output: Context, Not Just Numbers
&lt;/h2&gt;

&lt;p&gt;Here's what you see in PC_Workman when a spike happens:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before (Task Manager):&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;CPU: 87%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (PC_Workman):&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;⚠️ CPU spike: 87% (baseline: 42%, delta: +45%)
Chrome.exe - started 3 hours ago
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Same data. Different story.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One gives you anxiety. The other gives you action.&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%2Fzhln3qorhsofbhzqm1o3.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%2Fzhln3qorhsofbhzqm1o3.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PC Workman 1.6.8 - My PC - Center of Actions.
STATS &amp;amp; ALERTS - Long term monitoring your components usage, process usage. And mainly time-travel TEMP and Voltages alerts about spikes, or suspected moments. Optimization &amp;amp; Services - For optimize and improve your PC performance. First Setup &amp;amp; Drivers - All for setup your new device/new os. Stability Tests - For check about correctly working of PC Workman and Database check. Your Account-Details - Soon :)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Implementation Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Handles 5 Metrics With Same Logic
&lt;/h3&gt;

&lt;p&gt;The beauty of this design: &lt;strong&gt;reusable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same &lt;code&gt;_check_metric&lt;/code&gt; function handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU usage&lt;/li&gt;
&lt;li&gt;RAM usage&lt;/li&gt;
&lt;li&gt;GPU usage
&lt;/li&gt;
&lt;li&gt;CPU temperature&lt;/li&gt;
&lt;li&gt;GPU temperature
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_and_log_spike&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_avg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ram_avg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gpu_avg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;cpu_temp&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="n"&gt;gpu_temp&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="n"&gt;baseline&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_baseline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Check each metric with same logic
&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_metric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&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="n"&gt;cpu_avg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                      &lt;span class="n"&gt;baseline&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_avg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
                      &lt;span class="n"&gt;SPIKE_THRESHOLD_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;CPU usage&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="nf"&gt;_check_metric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&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&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_avg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                      &lt;span class="n"&gt;baseline&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_avg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                      &lt;span class="n"&gt;SPIKE_THRESHOLD_RAM&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 usage&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ... and so on
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean. Maintainable. Scalable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance: Cached Baselines
&lt;/h3&gt;

&lt;p&gt;Baseline queries hit SQLite. Could be slow.&lt;/p&gt;

&lt;p&gt;Solution: 60-second cache.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;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;_baseline_cache_time&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="ow"&gt;and&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;_baseline_cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_baseline_cache&lt;/span&gt;  &lt;span class="c1"&gt;# Use cached data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Query once per minute, not once per second.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storage: SQLite Events Table
&lt;/h3&gt;

&lt;p&gt;All events logged to database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;severity&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="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="n"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;process_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&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="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&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;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Historical tracking (what spiked last week?)&lt;/li&gt;
&lt;li&gt;Pattern detection (Chrome spikes every Tuesday?)&lt;/li&gt;
&lt;li&gt;Exportable data&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I Learned Building This
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Users Don't Need More Data
&lt;/h3&gt;

&lt;p&gt;Early versions of PC_Workman showed 20+ metrics.&lt;/p&gt;

&lt;p&gt;Users ignored them all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Context, no quantity.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Rate Limiting Is User Experience
&lt;/h3&gt;

&lt;p&gt;First version: no rate limiting.&lt;br&gt;&lt;br&gt;
Result: 500 alerts per hour. Unusable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Silence is a feature.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Personalization.
&lt;/h3&gt;

&lt;p&gt;"50% CPU is high" works for nobody.&lt;br&gt;&lt;br&gt;
YOUR 50% vs MY 50% = different stories.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PC Workman 1.6.8 - hck_GPT Insights
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;&lt;strong&gt;EventDetector stats:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;~30 lines core logic&lt;/li&gt;
&lt;li&gt;Handles 5 metrics&lt;/li&gt;
&lt;li&gt;Max 1 alert per metric per 5 min&lt;/li&gt;
&lt;li&gt;Baseline cached 60 sec&lt;/li&gt;
&lt;li&gt;3 severity levels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PC_Workman stats:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;800+ hours development&lt;/li&gt;
&lt;li&gt;Built on 94°C laptop&lt;/li&gt;
&lt;li&gt;v1.6.8 current (v2.0 -&amp;gt; Microsoft Store, Q3 2026)&lt;/li&gt;
&lt;li&gt;60+ downloads&lt;/li&gt;
&lt;li&gt;17 stars&lt;/li&gt;
&lt;li&gt;Open source, MIT licensed&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;PC_Workman is open source.&lt;/p&gt;

&lt;p&gt;EventDetector is in &lt;code&gt;hck_stats_engine/events.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Download, run, break it, improve it.&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;br&gt;
&lt;strong&gt;File what I show you:&lt;/strong&gt; &lt;a href="https://github.com/HuckleR2003/PC_Workman_HCK/blob/main/hck_stats_engine/events.py" rel="noopener noreferrer"&gt;PC_Workman_HCK/hck_stats_engine/events.py&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building in public.&lt;/strong&gt; Code Autopsy every Wednesday.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Twitter: &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;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;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%2F2zaryuy4bs91p4bpk7yn.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%2F2zaryuy4bs91p4bpk7yn.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Week: Wednesday Code Autopsy #2
&lt;/h2&gt;

&lt;p&gt;Topic: ProcessAggregator - how PC_Workman tracks which apps eat your CPU without destroying performance.&lt;br&gt;
See you Wednesday.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Questions? Comments? Roasts? I'm building in public. Feedback welcome.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I’m &lt;strong&gt;Marcin Firmuga&lt;/strong&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%2Fv5uvx9rspkvr86r98je9.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%2Fv5uvx9rspkvr86r98je9.png" alt=" "&gt;&lt;/a&gt;&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;/p&gt;

&lt;p&gt;This is the first time I’ve given one of my projects a real, dedicated home.&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;&lt;strong&gt;But this one?&lt;/strong&gt; 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>ai</category>
    </item>
  </channel>
</rss>
