<?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: Jayant Jeet Tomar</title>
    <description>The latest articles on DEV Community by Jayant Jeet Tomar (@halfbloodcoder).</description>
    <link>https://dev.to/halfbloodcoder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F481134%2F6123d31d-a455-4d40-81c0-9006a7293b76.jpg</url>
      <title>DEV Community: Jayant Jeet Tomar</title>
      <link>https://dev.to/halfbloodcoder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/halfbloodcoder"/>
    <language>en</language>
    <item>
      <title>My phone counts every reel I watch, and a 1.9 GB Gemma judges me for it</title>
      <dc:creator>Jayant Jeet Tomar</dc:creator>
      <pubDate>Thu, 22 Oct 2026 07:35:18 +0000</pubDate>
      <link>https://dev.to/halfbloodcoder/my-phone-counts-every-reel-i-watch-and-a-19-gb-gemma-judges-me-for-it-c68</link>
      <guid>https://dev.to/halfbloodcoder/my-phone-counts-every-reel-i-watch-and-a-19-gb-gemma-judges-me-for-it-c68</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Sloths have one big idea: never do work you can make something else do.&lt;/p&gt;

&lt;p&gt;So I built an app that does the one chore I'm worst at: honestly knowing how many reels I watched today.&lt;/p&gt;

&lt;p&gt;The idea came from watching my parents. Almost all their free time was going to reels. Then I looked around and realised it isn't just them: babies, kids, millennials like me, parents, even grandparents. Everyone is scrolling in their spare moments. I don't think it's evil. But most of it isn't doing much for us, and most of us don't notice. So I built something that quietly shows you the number and says it out loud, kindly, or with a roast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scroll Sloth&lt;/strong&gt; is an Android app that counts the short videos you watch in Instagram Reels, YouTube Shorts, and Facebook Reels. It shows daily, weekly and monthly totals, and gives you two scores: &lt;strong&gt;laziness&lt;/strong&gt; and &lt;strong&gt;unproductivity&lt;/strong&gt;, each with a "why this score" breakdown. Every night at about 00:30, while the phone is charging, a small Gemma model running &lt;em&gt;on the phone&lt;/em&gt; writes a two-sentence verdict about your day. You pick the tone: gentle, or roast.&lt;/p&gt;

&lt;p&gt;The lazy part: you don't log anything, you don't open anything, and the verdict is waiting in the morning. The only effort is the shame.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6sf8sc8ucr9ijmuy4pxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6sf8sc8ucr9ijmuy4pxi.png" alt="My Today's screenshot" width="651" height="1271"&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9e9nivaqhbb7r8cp3t81.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9e9nivaqhbb7r8cp3t81.png" alt="Gemma verdict" width="800" height="985"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/f8k2S9SarAA" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Landing page and install guide:&lt;/strong&gt; &lt;a href="https://jayant-jeet.github.io/Scroll-Sloth/" rel="noopener noreferrer"&gt;https://jayant-jeet.github.io/Scroll-Sloth/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Download:&lt;/strong&gt; signed APK (with SHA-256 checksum) on the &lt;a href="https://github.com/Jayant-Jeet/Scroll-Sloth/releases/latest" rel="noopener noreferrer"&gt;latest release&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Play Store listing is still waiting on paperwork, so for now it installs straight from GitHub. On Android 13+ you first need &lt;em&gt;App info &amp;gt; menu &amp;gt; Allow restricted settings&lt;/em&gt; before you can switch on the accessibility service. The onboarding screen walks you through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Jayant-Jeet" rel="noopener noreferrer"&gt;
        Jayant-Jeet
      &lt;/a&gt; / &lt;a href="https://github.com/Jayant-Jeet/Scroll-Sloth" rel="noopener noreferrer"&gt;
        Scroll-Sloth
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Scroll Sloth&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Scroll Sloth is an Android-only, on-device app for counting short-form video sessions in Instagram, YouTube Shorts, and Facebook Reels. The current build includes onboarding, rule-driven reel detection, daily/weekly/monthly statistics with laziness and unproductivity scores (with a "why this score" breakdown), on-device commentary (Gemma or templates), and the debug &lt;strong&gt;Rule Inspector&lt;/strong&gt; used to collect the real UI structure that detection rules are built from.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Website and install guide:&lt;/strong&gt; &lt;a href="https://jayant-jeet.github.io/Scroll-Sloth/" rel="nofollow noopener noreferrer"&gt;https://jayant-jeet.github.io/Scroll-Sloth/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Download:&lt;/strong&gt; &lt;a href="https://github.com/Jayant-Jeet/Scroll-Sloth/releases/latest" rel="noopener noreferrer"&gt;latest release&lt;/a&gt; (signed APK and its SHA-256 checksum)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Architecture overview&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app&lt;/code&gt;: the only Android application module, written in Kotlin with Jetpack Compose and Material 3.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;com.halfbloodcoder.scrollsloth.AppContainer&lt;/code&gt;: hand-written dependency container created by &lt;code&gt;ScrollSlothApplication&lt;/code&gt; and shared by the activity and the accessibility service (one DataStore instance per process).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;com.halfbloodcoder.scrollsloth.detect&lt;/code&gt;: supported platforms, the detection-rules schema, loader and repository, &lt;code&gt;RulesUpdater&lt;/code&gt;/&lt;code&gt;HttpRulesFetcher&lt;/code&gt; (rules fetch), &lt;code&gt;AppStatuses&lt;/code&gt; (per-app status), &lt;code&gt;RuleEngine&lt;/code&gt; (node tree → &lt;code&gt;DetectorEvent&lt;/code&gt;), the pure-Kotlin &lt;code&gt;ReelStateMachine&lt;/code&gt; (dwell, dedupe, resets), &lt;code&gt;ReelDetector&lt;/code&gt;…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Jayant-Jeet/Scroll-Sloth" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Is it safe? Privacy in plain words
&lt;/h2&gt;

&lt;p&gt;Privacy turned out to be the thing everyone cared about most. When I shared the app with friends for feedback, "wait, is this watching my phone?" was the first question every time. Fair question. So here are the honest answers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Scroll Sloth counts your reels. It doesn't watch them.&lt;/strong&gt;&lt;br&gt;
It saves only the time, the app and how long you stayed. No captions, no names, no screen content. Everything stays on your phone. No server, nothing to sell. You can pause it, export it or delete it anytime. And the code is open for anyone to check.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What does it look at?&lt;/strong&gt;&lt;br&gt;
Only three apps: Instagram, YouTube and Facebook. Android itself enforces this. The app was never given permission to see anything else, so your messages, photos, banking apps and browser are out of its reach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does it look at inside those apps?&lt;/strong&gt;&lt;br&gt;
Only one thing: "Is a reel on the screen, and did it just change?" It doesn't read captions, comments, usernames or links. It can't tell what you watched. It only knows that you watched one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does it save?&lt;/strong&gt;&lt;br&gt;
Three small facts per reel: the time, which app, and how many seconds you stayed. That's all. It's like a tally mark on a wall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does it never save?&lt;/strong&gt;&lt;br&gt;
What the reel was about, who posted it, what it said, or what was on your screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does anything leave my phone?&lt;/strong&gt;&lt;br&gt;
Your reel data, never. There is no server, so there's nowhere for it to go. The AI that writes your daily verdict (Gemma) runs on your phone too. The app makes only two internet requests, and both just &lt;em&gt;download&lt;/em&gt; public files:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The AI model, once.&lt;/li&gt;
&lt;li&gt;A small file of "how to spot a reel" rules, once a week, plus a tiny signature file. The app checks that signature before using the rules, so a tampered file is rejected. You can switch this off in settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neither request carries your data. There is no analytics tool and no ad tool inside the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I stay in control?&lt;/strong&gt;&lt;br&gt;
Yes, all of this is in Settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pause counting at any time.&lt;/li&gt;
&lt;li&gt;Export your data, or delete all of it with one tap.&lt;/li&gt;
&lt;li&gt;Turn off the app's permission in Android settings whenever you want.&lt;/li&gt;
&lt;li&gt;Uninstall, and everything goes with it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How do I know you're not fibbing?&lt;/strong&gt;&lt;br&gt;
Don't take my word for it. The whole app is open source, so anyone can read the code. The privacy rules are written in the README, and the app limits itself to those three apps in its own configuration file, not just in a promise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One honest note.&lt;/strong&gt;&lt;br&gt;
Accessibility is a powerful Android permission, and you should always be careful about who you give it to. That's why I made the app open, kept it to three apps, and keep it fully on your phone. Only download it from the official link, and check the checksum on the release page if you want to be extra sure.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The rule: the model writes words, plain code does maths.&lt;/strong&gt;&lt;br&gt;
Every number in the app comes from a deterministic Kotlin engine. Laziness is a weighted sum of four things: how many reels (45%), how far above my own 28-day baseline (15%), how many were watched late at night (20%) and my longest unbroken session (20%). Unproductivity is minutes watched against a daily budget. Gemma never touches a number. It only gets a small JSON block of facts and is told to write two sentences using only those.&lt;/p&gt;

&lt;p&gt;Then a checker called &lt;code&gt;NumberGuard&lt;/code&gt; reads whatever Gemma wrote. Every number in the text (digits, percentages, even "seven") has to be in an allow-list built from the facts. If one isn't, Gemma gets one retry with the bad numbers named. If it fails again, a template engine writes the verdict instead. The card shows a badge, "Written by Gemma on your phone" or "Template", so I always know who to blame.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Counting reels in apps that don't tell you how they're built.&lt;/strong&gt;&lt;br&gt;
Instagram, YouTube and Facebook don't publish their UI structure, and I didn't want to guess view IDs from memory. So before writing any detection, I built a &lt;strong&gt;Rule Inspector&lt;/strong&gt;: a draggable Capture button (an accessibility overlay, so it needs no extra permission) that saves the structure of the screen: view IDs, classes, sizes, and only whether text exists, never the text itself. I captured a reel screen and a home feed in each app on my Galaxy S24 Ultra, diffed them, and worked out the detection rules from what I could actually see, with GitHub Copilot as my pair for reading the captures. Facebook obfuscates its IDs, so its rule leans on class, size, and position instead.&lt;/p&gt;

&lt;p&gt;The rules live in a versioned &lt;code&gt;detection-rules.json&lt;/code&gt;, and the unit tests replay my real captures, so a rule change that stops matching them fails the build. The app checks for new rules weekly. When Instagram changes its layout (it will), I fix a JSON file instead of shipping a new APK. A reel counts after 2 seconds, loops are capped at 120 seconds, and scrolling back to a reel within 60 seconds doesn't count it twice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Signed rules.&lt;/strong&gt; After a reader asked whether the rules file could be tampered with, I added signatures. Official rule updates are signed offline with an ECDSA P-256 key. The app has two public keys built in (primary and backup), checks the signature before it even parses the file, and keeps its current rules if the check fails. Rules a user imports by hand, or fetches from a custom address, show up as "Unverified" and need confirmation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma 4 on the phone, and the bug that made it speak in tongues.&lt;/strong&gt;&lt;br&gt;
The writer is Gemma 4 E2B (instruction-tuned, about 1.9 GB, Apache 2.0, not gated) running through LiteRT-LM on the GPU, with greedy decoding and a 60-token cap. A verdict takes a few seconds on my phone.&lt;/p&gt;

&lt;p&gt;The first outputs were fun for the wrong reasons: one sentence told me I had "watchedヒル closely". Mid-sentence, a Japanese word had wandered in. The cause turned out to be a known GPU issue in the public LiteRT-LM tracker (#3879), and Copilot helped me read the issue and turn it into a fix. Switching to FLOAT32 activations with a separate GPU cache directory solved it. I also taught &lt;code&gt;NumberGuard&lt;/code&gt; to treat unexpected non-Latin letters as a sign of garbled output and fall back to a template.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pipeline.&lt;/strong&gt;&lt;br&gt;
GitHub Actions runs the tests, validates the rules file on every pull request, builds the signed release APK on each tag, and deploys the landing page. Copilot also helped me fix a workflow that wouldn't run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Kotlin, Jetpack Compose, Room, DataStore, WorkManager, LiteRT-LM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A tracker of my own habits has no business in someone else's cloud.&lt;/strong&gt; Knowing when I scroll, for how long, and how late is about as personal as data gets. With an open-weight model on the phone, the model comes to the data, not the other way round. Nothing about my reel habit leaves the device.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open weights meant zero friction.&lt;/strong&gt; Gemma 4 E2B is Apache 2.0 and not gated, so there's no token or terms-acceptance step in the downloader. And once downloaded, it works on a plane for free, forever. There's no per-call bill for a tool that fires once a night.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open issue trackers saved my afternoon.&lt;/strong&gt; The garbled-output bug had a public issue with a matching symptom. That's the difference between "my model is broken" and "this is a known GPU precision problem, here's the workaround".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open rules, open repo.&lt;/strong&gt; Because detection is a JSON file in a public repo, anyone with a different phone or a newer Instagram can capture, fix and open a PR. The README has a step-by-step guide for it. And because the code is open, my privacy claims above are something you can check, not just believe.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Where closed worked better, honestly:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A cloud model would have been easier to set up and would run on any phone. Mine needs a capable GPU and about 2 GB of storage, and falls back to templates otherwise.&lt;/li&gt;
&lt;li&gt;My promo video was made with ElevenLabs, a closed tool. It was easy and the result looks great. I'm not going to pretend an open pipeline would have been faster to get there.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;Doing this by hand is exactly as annoying as it sounds. My calibration screen asks me to tap a &lt;strong&gt;+1&lt;/strong&gt; button for every reel I &lt;em&gt;really&lt;/em&gt; watched so I can compare it to what the app counted. Scroll Sloth is the thing that makes that tap-by-tap tallying unnecessary.&lt;/p&gt;

&lt;p&gt;I tested it on my own phone against my own thumb. Results of calibration runs (my manual count vs. the app's count):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;App&lt;/th&gt;
&lt;th&gt;My count&lt;/th&gt;
&lt;th&gt;Scroll Sloth's count&lt;/th&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Instagram Reels&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YouTube Shorts&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Facebook Reels&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I knew, I watched a little insta reels before I went to sleep or when work was slow, but watching the actual numbers left me to wonder how much time I am wasting being unproductive. It was a wake-up call. I plan to decrease the amount of time I spend watching reels and maybe do something productive (like reading a book or learn to play guitar 😅)&lt;/p&gt;

&lt;p&gt;I shared the app with my friends, and they liked it. But the immediate question that they asked was - "What about privacy?". So, I had to explain the whole project philosophy, and I won their trust finally.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Can't Do (Yet)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Android only. iOS has no equivalent of the accessibility service.&lt;/li&gt;
&lt;li&gt;It depends on three apps' screen structure, which they can change in any update. The rules were calibrated on one phone (Galaxy S24 Ultra, Android 16), so other devices, app versions, or languages may need new rules.&lt;/li&gt;
&lt;li&gt;Counting is close, not exact: picture-in-picture, split-screen, and reels inside DMs or Stories may be missed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma 4 E2B writing every verdict on-device through LiteRT-LM, wrapped in a number checker so it can't invent stats.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot:&lt;/strong&gt; Copilot helped me work out the detection rules for all three apps from my Rule Inspector captures, find the cause of the garbled Gemma output by reading an open GitHub issue, and fix a failing GitHub Actions workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs:&lt;/strong&gt; The promo video above was made with ElevenLabs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now if you'll excuse me, I have a roast waiting for me in the morning. 🦥&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>hacktoberfest</category>
      <category>android</category>
    </item>
    <item>
      <title>My dad's health insurance covered nothing, so I built an AI that reads the fine print for him</title>
      <dc:creator>Jayant Jeet Tomar</dc:creator>
      <pubDate>Wed, 14 Oct 2026 18:26:13 +0000</pubDate>
      <link>https://dev.to/halfbloodcoder/my-dads-health-insurance-covered-nothing-so-i-built-an-ai-that-reads-the-fine-print-for-him-2c72</link>
      <guid>https://dev.to/halfbloodcoder/my-dads-health-insurance-covered-nothing-so-i-built-an-ai-that-reads-the-fine-print-for-him-2c72</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/devteam/join-the-hacktoberfest-open-source-ai-challenge-side-hustle-2550-in-prizes-across-18-winners-55ba"&gt;Hacktoberfest Open-Source AI Challenge: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Insurance Samjho&lt;/strong&gt; ("samjho" = "understand", for the non-Hindi readers). You upload your health insurance policy PDF, and it tells you, in plain language, where the policy will quietly leave you paying out of pocket.&lt;/p&gt;

&lt;p&gt;Here's why it exists.&lt;/p&gt;

&lt;p&gt;A few insurance agents got hold of my father. You know the type: warm smile, big promises, "sir, everything is covered." He bought a policy. Then he was hospitalized for knee pain, and &lt;em&gt;nothing&lt;/em&gt; was covered. Nothing. Zero. The "everything" in "everything is covered" was doing a lot of heavy lifting.&lt;/p&gt;

&lt;p&gt;So I did what any slightly furious son would do: I read the entire policy. Forwards. Then backwards, in case the plot twist was at the end. Verdict: a deeply mediocre policy, nowhere near worth the premium he was paying.&lt;/p&gt;

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

&lt;p&gt;And my dad isn't special here. Most people holding a health policy have no idea what's actually in it. Policy documents are 40+ pages of legal English written by people who are paid by the word and punished by clarity. Nobody reads them until the hospital bill arrives, and by then it's a bit late for reading.&lt;/p&gt;

&lt;p&gt;So now you upload the PDF and get &lt;strong&gt;risk-level cards&lt;/strong&gt;: long waiting periods for pre-existing diseases, room rent caps, deductibles, sub-limits, co-pays and more. Every finding links back to the &lt;strong&gt;exact quote&lt;/strong&gt; from your policy, so you're not trusting an AI's vibes. You can check it yourself.&lt;/p&gt;

&lt;p&gt;The whole site also works in &lt;strong&gt;Hindi&lt;/strong&gt;, because the people who most need this are often the least served by English-only tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhkyyo642jyyhk0et6w3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhkyyo642jyyhk0et6w3i.png" alt="The landing page: pick Online or Local LLM, then drop your PDF" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who would pay for this?&lt;/strong&gt; Anyone about to buy, renew, or claim on a policy. That's a &lt;em&gt;lot&lt;/em&gt; of people. It's also the exact tool I wish someone had handed my dad before the agent finished his pitch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://www.insurancesamjho.tech/" rel="noopener noreferrer"&gt;insurancesamjho.tech&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upload a policy and the app walks through four steps: segmenting the PDF pages, extracting coverage, cross-checking quotes against the original text, and building an "Out-of-Pocket Map."&lt;/p&gt;

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

&lt;p&gt;Then you get your results. For the sample policy below it found 13 things worth a look: 4 high risk (red), 8 medium (yellow), and 1 note. Start with the red cards.&lt;/p&gt;

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

&lt;p&gt;And the same results in Hindi, one click away:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Jayant-Jeet" rel="noopener noreferrer"&gt;
        Jayant-Jeet
      &lt;/a&gt; / &lt;a href="https://github.com/Jayant-Jeet/insurance-samjho" rel="noopener noreferrer"&gt;
        insurance-samjho
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🛡️ Insurance Samjho (Health Insurance Check Karo)&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Hacktoberfest 2026 - Week 2 (Side Hustle) Submission&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Insurance Samjho is a privacy-first, local-AI web application that reads dense health insurance policies and instantly generates an "Out-of-Pocket Map." It tells users exactly when they are covered and when they will have to pay from their own pocket—without ever sending highly sensitive financial and medical documents to closed-source cloud providers.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 The Architecture&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;This project utilizes a modern, decoupled full-stack architecture built for local-first AI:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Frontend (React / Vite / Tailwind):&lt;/strong&gt; A high-trust, responsive UI utilizing Apollo Client to map financial risk via dynamic scenario cards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway (Java Spring Boot / GraphQL):&lt;/strong&gt; Orchestrates the data flow. Handles multipart PDF uploads via REST and serves complex, nested UI data via GraphQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ML Microservice (Python / FastAPI):&lt;/strong&gt; Runs &lt;code&gt;vLLM&lt;/code&gt; with &lt;strong&gt;Gemma 4 (12B)&lt;/strong&gt;. It segments PDFs and uses constrained decoding (&lt;code&gt;guided_json&lt;/code&gt;) to…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Jayant-Jeet/insurance-samjho" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The pipeline is simple on purpose:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Upload&lt;/strong&gt; the policy PDF.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parse&lt;/strong&gt; it with &lt;strong&gt;Gemma&lt;/strong&gt; (&lt;code&gt;gemma-2-9b-it&lt;/code&gt;) and extract the sections that matter: waiting periods, exclusions, caps, co-pays.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-check&lt;/strong&gt; each finding against the original text, so every card carries the exact supporting quote.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Translate&lt;/strong&gt; on demand into Hindi with &lt;strong&gt;IndicTrans2&lt;/strong&gt; (AI4Bharat), another open model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The part I'm most pleased with is that you choose &lt;strong&gt;where the model runs&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local LLM (Private):&lt;/strong&gt; vLLM serves Gemma on your own machine, so your policy never leaves your device. The site has a built-in setup panel with the exact commands for Windows (WSL2), macOS, and Linux, plus a "Refresh Status" button, so you can see that the parser and translator are running before it lets you upload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Online LLM:&lt;/strong&gt; for the 95% of humans who don't have a GPU lying around, the same Gemma setup is hosted on &lt;strong&gt;Modal&lt;/strong&gt;. I'll be honest: the cold start is my villain origin story. On a cold start, parsing one policy sometimes took close to &lt;em&gt;30 minutes&lt;/em&gt;. I stared at a spinner long enough to reconsider my life choices (and my hairline). Once the container is warm it's fine, and I haven't found a fix I can afford yet, so for now that's the price of "free." If you have a GPU, Local mode skips the wait entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The backend runs on &lt;strong&gt;Render&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The frontend lives on a &lt;strong&gt;.tech domain&lt;/strong&gt;, which I got free for a year through the Hacktoberfest promo. If people actually start using Insurance Samjho (fingers crossed), I'll happily keep it there and renew every year.&lt;/p&gt;

&lt;p&gt;I also leaned on the &lt;strong&gt;GitHub Copilot coding agent&lt;/strong&gt; for the part I was dreading most: model setup. I have two models (Gemma for parsing, IndicTrans2 for Hindi), each with its own docs, serving flags, and parameters that all look equally mysterious until something breaks. Normally that's a weekend of tabs, GitHub issues, and muttering. Copilot read through the options, configured both models, and helped me debug performance problems, so I could spend my time on the actual product. Model setup went from "ugh" to a piece of cake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known rough edges:&lt;/strong&gt; it's a 9B model, not a lawyer. Sometimes it repeats a finding in two cards (you can spot the pre-existing waiting period twice in the screenshot above) or flags a benefit as a risk. That's exactly why every card shows the exact quote from your policy: so you can verify it instead of trusting me. Please treat it as a "questions to ask your insurer" list, not legal advice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Because of what a health insurance policy &lt;em&gt;is&lt;/em&gt;. It's full of personal health and financial details. Uploading that to a random closed API and hoping for the best felt wrong to me.&lt;/p&gt;

&lt;p&gt;Open-weight models let me do things a closed API couldn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy:&lt;/strong&gt; run Gemma locally, so the document never leaves the user's machine. A closed API can't offer that option at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language:&lt;/strong&gt; IndicTrans2 is built for Indian languages. For a product aimed at people like my dad, "Hindi support" shouldn't mean a translation that reads like it was dictated to a very confused robot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No lock-in, no meter I can't control:&lt;/strong&gt; I'm a solo dev with a free domain and a Modal bill I'd rather not look at, so open models are the only reason this is financially possible. With a closed API, every policy a stranger uploads would cost me per token, and a tool people use once or twice a year can't really charge for that.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;p&gt;The first (and toughest) user was my dad. He's the reason this project exists, so it felt right that he got to try it first.&lt;/p&gt;

&lt;p&gt;His review: he &lt;strong&gt;loved it&lt;/strong&gt;. His only complaint was the parsing time, which is fair, and see the Modal section above for my own pain on that.&lt;/p&gt;

&lt;p&gt;He now understands his policy far better than he did after paying the premiums for a year. Then something happened that I did not plan for: I caught him taking screenshots of his results and &lt;strong&gt;sending them to the insurance agent on WhatsApp&lt;/strong&gt;. The agent who sold him the policy. The one who said everything was covered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExd3ZoeTJ6N2kyZGlzcmZsNXdyNzZ1YzNmcTljNXo0eTh2NmU2aDZxdCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/dB16tYGyHzov7EzN5D/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExd3ZoeTJ6N2kyZGlzcmZsNXdyNzZ1YzNmcTljNXo0eTh2NmU2aDZxdCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/dB16tYGyHzov7EzN5D/giphy.gif" alt="sounds like a scam" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would he pay for it? Obviously not. He's a typical Indian dad, and the idea of paying for a website is deeply offensive to him. But he did send the link to a bunch of relatives and then &lt;em&gt;phoned them&lt;/em&gt; to explain how it works. That's a better growth strategy than anything I could have planned.&lt;/p&gt;

&lt;p&gt;I've built a lot of things, but I've never seen one of them used to confront someone in real time. 10/10 would recommend to every family with an agent problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma does the policy parsing, both locally and online&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render:&lt;/strong&gt; hosts the backend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot:&lt;/strong&gt; model setup, configuration, and performance debugging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of a .tech Domain:&lt;/strong&gt; &lt;a href="https://www.insurancesamjho.tech/" rel="noopener noreferrer"&gt;insurancesamjho.tech&lt;/a&gt;, free for a year via the Hacktoberfest promo, and I plan to renew it if people adopt the site&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One Last Thing ☕
&lt;/h2&gt;

&lt;p&gt;If Insurance Samjho saved you from a bad policy (or finally made you read the one you have), I'd love to hear about it. The results page also asks if it was helpful, and if it was, you can &lt;a href="https://buymeacoffee.com/halfbloodcoder" rel="noopener noreferrer"&gt;buy me a coffee&lt;/a&gt;. It funds the Modal GPU bill and my ongoing recovery from reading insurance PDFs.&lt;/p&gt;

&lt;p&gt;And if you ever meet an insurance agent who says "everything is covered," please upload first, believe later.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsn1nwq778ufdi99japwh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsn1nwq778ufdi99japwh.webp" alt=" " width="800" height="664"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>4,271 plants, zero bars: BioDex, an offline Pokédex for the plants around you</title>
      <dc:creator>Jayant Jeet Tomar</dc:creator>
      <pubDate>Wed, 07 Oct 2026 03:03:54 +0000</pubDate>
      <link>https://dev.to/halfbloodcoder/biodex-i-built-a-plant-collector-simulation-to-help-you-touch-grass-13ll</link>
      <guid>https://dev.to/halfbloodcoder/biodex-i-built-a-plant-collector-simulation-to-help-you-touch-grass-13ll</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Hacktoberfest said “touch grass"... so I built an app that literally makes you do it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZnh1NmZhZHd3czYzNDg3dmcwNXliMjdtYWFncmxob2g5NXE2eHQ0eSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/T7xwGxSMc1oUfvSRNh/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img width="480" src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZnh1NmZhZHd3czYzNDg3dmcwNXliMjdtYWFncmxob2g5NXE2eHQ0eSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/T7xwGxSMc1oUfvSRNh/giphy.gif" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Meet BioDex — an Android game where plants are your Pokémon cards. Snap a pic 🌿📸, wait a few seconds, and boom: you’ve got a collectible card with the plant’s name, rarity, and a fun little field note. XP, a daily streak, and a daily field mission push you to go find the next one. The only way to fill the Dex is to leave the house.&lt;/p&gt;

&lt;p&gt;The screen is meant to be the shortest part of the walk: one photo, five seconds of waiting, then the phone goes back in your pocket. This Saturday morning I tried it for 30 minutes in my society’s park and collected 8 cards. It took me back to my biology classes, where we learned the scientific and common names of plants and animals. I used to remember so many of them, like Mangifera indica for mango. It was a nice flashback to my school days.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌱 Features:
&lt;/h3&gt;

&lt;p&gt;• Camera-based plant capture for collectible cards&lt;br&gt;
• Learn scientific names and common names of flora&lt;br&gt;
• Rarity system (S‑rank, rare, common) for added challenge&lt;br&gt;
• Offline gameplay — no internet required (apart from downloading the model on first run)&lt;br&gt;
• Educational yet fun: explore, collect, and build your own flora deck&lt;br&gt;
• Safe and private: no personal data collected or shared&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;A short screen recording shows BioDex in action:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/_vVePeb4DfE" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  🎮Try it
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Join the closed testing group through this Google Group: &lt;a href="https://groups.google.com/g/biodextesters/" rel="noopener noreferrer"&gt;BioDex Closed Testers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Or download the signed APK from GitHub: &lt;a href="https://github.com/Jayant-Jeet/BioDex/releases/download/v1.1.3/BioDex-v1.1.3.apk" rel="noopener noreferrer"&gt;BioDex-v1.1.3.apk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Everything lives in one repo: the Android app, the model export script, and the Gemma note generator.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Jayant-Jeet" rel="noopener noreferrer"&gt;
        Jayant-Jeet
      &lt;/a&gt; / &lt;a href="https://github.com/Jayant-Jeet/BioDex" rel="noopener noreferrer"&gt;
        BioDex
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;BioDex&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;BioDex is an Android-first, offline plant-collector MVP built with Kotlin, Jetpack Compose, CameraX, and the official Imageomics BioCLIP 2.5 ViT-H/14 image encoder. Capture a plant photo, find its closest match in a 4,271-species field guide, generate a field card, save it locally, and share the PNG.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Prepare the official model&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;The app uses the official checkpoint, not the smaller distilled student. The upstream OpenCLIP/PyTorch checkpoint is about &lt;strong&gt;3.94 GB&lt;/strong&gt;. Before building the app:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install Python 3.13 and create the project environment with &lt;code&gt;py -3.13 -m venv .venv&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Install the model-export dependencies: &lt;code&gt;.venv\Scripts\python.exe -m pip install -r scripts\requirements-bioclip-export.txt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;.venv\Scripts\python.exe scripts\export-bioclip-25-onnx.py&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The exporter verifies the existing 4,271-label embedding table against its published SHA-256 (the model author identifies it as the teacher's text-embedding space), downloads the checkpoint at a pinned Hugging Face revision, exports an FP16 ONNX image encoder, and verifies its output against OpenCLIP and…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Jayant-Jeet/BioDex" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;BioDex is a Kotlin app: Jetpack Compose for the UI, CameraX for the camera, ONNX Runtime for the model. The interesting part is what the model is and where each half of it runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BioCLIP, split in half.&lt;/strong&gt; Only the image encoder runs on the phone. The 4,271 plant names were turned into embeddings ahead of time and ship as a table. At runtime, a photo becomes a vector, which is compared against that table with cosine similarity. The closest match becomes your card.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma at build time.&lt;/strong&gt; Gemma 4 E4B, running locally through Ollama, wrote a common name and a short field note for all 4,271 plants, once, with a resumable script. No language model runs on the phone. The notes describe the species, not your photo, and they can be wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shipping releases.&lt;/strong&gt; I run a GitHub Actions workflow manually and choose whether the change is a patch, a minor or a major release. It bumps the version, then builds a signed AAB for the Play Store and a signed APK for sharing locally, such as the v1.1.3 link above.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤦Things that went wrong (lol)
&lt;/h2&gt;

&lt;p&gt;Testing on my own phone turned up two problems: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Random objects came back as plants.&lt;/strong&gt; I photographed things that weren’t plants at all, and BioDex still returned the closest plant in the guide. Similarity always finds a nearest neighbour. I fixed it with a minimum cosine-similarity threshold of 0.45, so below that BioDex says it doesn’t recognise the photo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Plain-looking plants give false matches.&lt;/strong&gt; If the plant shows no distinguishing features, such as leaves and small buds but no recognisable flower, the model can still return a confident-looking wrong species. The threshold doesn’t catch this, because the photo is plant-like enough to pass. The similarity score isn’t a confidence level, so BioDex treats it as a suggestion, never a verdict.&lt;/p&gt;

&lt;h4&gt;
  
  
  Other rough edges:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Specimen #0001: the note said small pale flowers, and my photo was full of pink ones.&lt;/li&gt;
&lt;li&gt;Plants only. Animals and fungi aren’t in the guide, and a plant that isn’t listed can only come back as its closest cousin.&lt;/li&gt;
&lt;li&gt;Never use BioDex to decide whether a plant is edible, poisonous or medicinal. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExa2w0MXA4Zjh2aWYwZTRnbW9ubGNxN3h2bGoxYzd0MnVjZzN3dGMycyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/7CvTeIIxjF2aFP8Nlb/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img width="500" src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExa2w0MXA4Zjh2aWYwZTRnbW9ubGNxN3h2bGoxYzd0MnVjZzN3dGMycyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/7CvTeIIxjF2aFP8Nlb/giphy.gif" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;On the trail&lt;/th&gt;
&lt;th&gt;Open (BioCLIP, ONNX Runtime)&lt;/th&gt;
&lt;th&gt;Hosted vision API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No signal&lt;/td&gt;
&lt;td&gt;Works after one model download&lt;/td&gt;
&lt;td&gt;A spinner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Photos of your garden or kids&lt;/td&gt;
&lt;td&gt;Stay on the phone&lt;/td&gt;
&lt;td&gt;Uploaded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;No per-photo fee or API key&lt;/td&gt;
&lt;td&gt;Per call&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reproducibility&lt;/td&gt;
&lt;td&gt;Pinned revision, verified checksums, swappable encoder&lt;/td&gt;
&lt;td&gt;Can change underneath you&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Where closed would have won.&lt;/strong&gt; A hosted model would probably know far more than 4,271 plants, handle animals and fungi too, and wouldn't need 1.26 GB of my phone. Open cost me storage, RAM and one very long export script instead of money and privacy. For a game whose whole point is walking somewhere without signal, I'd make that trade again.&lt;/p&gt;

&lt;p&gt;I also didn't have to invent any of the hard parts. The Imageomics Institute trained and open-sourced the model, Nate Hamilton published a plant list and embeddings I could build on, Google's Gemma wrote the notes, and ONNX Runtime ran the whole thing on a phone. I wired them together and put a card game on top. That's open innovation at hobby scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Gemma.&lt;/strong&gt; Gemma 4 (E4B), running locally through Ollama, wrote the common name and field note for all 4,271 plants. It runs at build time, not on the phone, and the generator is a resumable script in the repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Use of GitHub Copilot.&lt;/strong&gt; I used Copilot to generate the GitHub Actions workflow that prepares releases. I choose patch, minor or major, and it versions the app and builds a signed AAB and APK, so each release is one click to publish to the Play Store or share locally.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
    </item>
    <item>
      <title>Interview Prep Buddy - Helping my friend prepare for his next job switch 🤫</title>
      <dc:creator>Jayant Jeet Tomar</dc:creator>
      <pubDate>Sat, 03 Oct 2026 19:35:02 +0000</pubDate>
      <link>https://dev.to/halfbloodcoder/interview-prep-buddy-1cn7</link>
      <guid>https://dev.to/halfbloodcoder/interview-prep-buddy-1cn7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Interview Prep Buddy&lt;/strong&gt;, a privacy‑first web app that helps my friend prepare for job interviews. The tool lets them upload their resume and paste a job description, then generates commonly asked interview questions tailored to their skills and experience. It also highlights strengths and gaps in the resume for that specific role, so they can prepare compensating answers.&lt;/p&gt;

&lt;p&gt;The app goes further with a mock interview mode: an AI voice asks questions, the user responds via speech, and the system scores their answers, identifies gaps, and adds follow‑up questions. It’s a supportive, interactive way to practice interviews without risking personal data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://www.interview-prep.online/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;interview-prep.online&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Jayant-Jeet" rel="noopener noreferrer"&gt;
        Jayant-Jeet
      &lt;/a&gt; / &lt;a href="https://github.com/Jayant-Jeet/interview-prep-buddy" rel="noopener noreferrer"&gt;
        interview-prep-buddy
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Interview Prep Buddy&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Interview Prep Buddy matches a resume to a job description, creates a role-aware question bank, and scores spoken or typed practice answers. Question generation runs in Ollama on each visitor's own device; the app does not use a hosted inference service.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Node.js (only needed to run the local static development server)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ollama.com/" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt; installed on the device running the browser&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;llama3.1:8b&lt;/code&gt; model&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Download the model in a terminal:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;ollama pull llama3.1:8b&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Keep Ollama running while using the app. The app connects from the browser directly to &lt;code&gt;http://localhost:11434&lt;/code&gt;; resume and job-description text are not sent to this project's web server.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run the hosted website with local Ollama&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install Ollama on the device running your browser and download the model:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;ollama pull llama3.1:8b&lt;/pre&gt;

&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On Windows, allow the hosted website's exact origin in Ollama. In PowerShell, run:&lt;/p&gt;
&lt;div class="highlight highlight-source-powershell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;setx OLLAMA_ORIGINS &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;https://www.interview-prep.online&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;OLLAMA_ORIGINS&lt;/code&gt; already has values, add…&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Jayant-Jeet/interview-prep-buddy" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open‑Source AI&lt;/strong&gt;: Powered by &lt;strong&gt;Llama&lt;/strong&gt; running locally via &lt;strong&gt;Ollama&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Minimalist single‑page web app (HTML, CSS, lightweight JS).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech Integration&lt;/strong&gt;: Browser‑based speech recognition and synthesis for interactive interviews.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluation&lt;/strong&gt;: AI + rule‑based scoring for clarity, technical accuracy, and confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The USP is that resumes and job descriptions are processed &lt;strong&gt;entirely on the user’s device&lt;/strong&gt;. Nothing is sent to external servers, ensuring complete privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Open innovation made this project possible. Running open‑weight models locally means users don’t depend on closed APIs or external services. They keep control of their data, while still benefiting from advanced AI capabilities. This freedom to adapt, extend, and run inference locally is exactly why open‑source AI matters — it empowers individuals to build tools that are both useful and trustworthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Best Use of GitHub Copilot&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Community Feedback
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fibwwd8z87ok2ljnjtq3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fibwwd8z87ok2ljnjtq3e.png" alt=" " width="537" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
