<?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: Raga Vinjanampati</title>
    <description>The latest articles on DEV Community by Raga Vinjanampati (@raga_vinjanampati).</description>
    <link>https://dev.to/raga_vinjanampati</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%2F4154945%2Fcd8d0973-6847-4547-9281-80dfd026b63d.png</url>
      <title>DEV Community: Raga Vinjanampati</title>
      <link>https://dev.to/raga_vinjanampati</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/raga_vinjanampati"/>
    <language>en</language>
    <item>
      <title>I lost 3 hackathons in a row. So I built a vampire judge to tell me why.</title>
      <dc:creator>Raga Vinjanampati</dc:creator>
      <pubDate>Sun, 01 Nov 2026 06:07:35 +0000</pubDate>
      <link>https://dev.to/raga_vinjanampati/i-lost-3-hackathons-in-a-row-so-i-built-a-vampire-judge-to-tell-me-why-4fkf</link>
      <guid>https://dev.to/raga_vinjanampati/i-lost-3-hackathons-in-a-row-so-i-built-a-vampire-judge-to-tell-me-why-4fkf</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26"&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Three weeks. Three projects. Three evenings refreshing the winners page.&lt;/p&gt;

&lt;p&gt;Week 1: nothing. Week 2: nothing. Week 3, I built a couch potato that told my mom to make me skip a date, filmed her agreeing with it, made three videos and rewrote the post four times. Nothing.&lt;/p&gt;

&lt;p&gt;Every time, I did the same thing afterwards: scrolled the winners list and wondered, &lt;em&gt;what did they have that I didn't?&lt;/em&gt; Nobody tells you. You just lose quietly.&lt;/p&gt;

&lt;p&gt;So for the final week, I summoned someone who would tell me. Someone strict. Someone who has sat on every jury since the fall of Rome. Someone with fangs.&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%2Fgr5gug3v8j7kztvnaleo.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%2Fgr5gug3v8j7kztvnaleo.png" alt="Judge Fangs: &amp;quot;Objection. To all of it.&amp;quot;" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Judge Fangs&lt;/strong&gt; is a 3,000-year-old vampire judge who reviews your hackathon submissions, emails and ideas, and tells you, bluntly and with evidence, exactly why they won't win.&lt;/p&gt;

&lt;p&gt;You give him two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The hackathon:&lt;/strong&gt; a link to the challenge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your work:&lt;/strong&gt; a DEV post, a GitHub repo, an email, or just an idea.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then he does what I never had time to do. He &lt;strong&gt;digs up the background&lt;/strong&gt;: the judging criteria, the prize categories, and the posts that actually won. He works out what those winners had in common. Then he &lt;strong&gt;checks your code&lt;/strong&gt; to see whether you really used what you claim. Finally he &lt;strong&gt;judges&lt;/strong&gt; you against each criterion, quoting your own words back at you as evidence.&lt;/p&gt;

&lt;p&gt;You get a score, the 3 biggest reasons you'd lose, 3 fixes, and a better title and opening. Then he reads his sentence aloud in a cold, ancient voice.&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%2Fqtdo7h0uxzfp95si51ru.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%2Fqtdo7h0uxzfp95si51ru.png" alt="Judge Fangs has six expressions" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;He's pixel art, drawn entirely in code, and he roams. On the website he wanders along the bottom of the page, taps his foot while he digs, and pulls out a gavel when the verdict lands. On my laptop, I press &lt;strong&gt;Ctrl+Shift+J&lt;/strong&gt; and he drops onto my actual screen, looks at whatever I'm working on, and judges &lt;em&gt;that&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;His catchphrase, for anything under 50: &lt;strong&gt;"Objection. To all of it."&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Try it (no install, no sign-up):&lt;/strong&gt;&lt;br&gt;
&lt;/p&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://fangs-web.onrender.com/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;fangs-web.onrender.com&lt;/span&gt;
          

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


&lt;p&gt;Paste any DEV post and challenge link and test out Judge Fangs.&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%2Ffn40235yrp8byp0sbzk6.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%2Ffn40235yrp8byp0sbzk6.png" alt="Meet Judge Fangs in a click!" width="799" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  I fed him my own losing entries
&lt;/h2&gt;

&lt;p&gt;This was the moment of truth. I gave Judge Fangs my Week 3 post, the one I was proudest of.&lt;/p&gt;

&lt;p&gt;I won't lie, this one stung a little.&lt;/p&gt;

&lt;p&gt;I put a lot of effort into Couch Potato, and seeing what separated it from the winning projects was humbling.&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%2F6eyyhog7502qnnswkjvi.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%2F6eyyhog7502qnnswkjvi.png" alt="Verdict Part-1" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But I'd rather have an AI point out my blind spots than keep making the same mistakes in every hackathon. Time to take notes, not just the L.&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%2F98heudsu08n16wjus9gg.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%2F98heudsu08n16wjus9gg.png" alt="Verdict Part-2" width="799" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My project had personality, but Judge Fangs wanted stronger technical proof, measurable impact, and a reason to beat the competition. &lt;/p&gt;

&lt;p&gt;Brutal? Yes. &lt;/p&gt;

&lt;p&gt;Useful? Unfortunately, also yes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real test: can he judge like the real judges?
&lt;/h2&gt;

&lt;p&gt;A judge who just insults everyone is easy to build. I wanted to know whether his taste matches the real jury's. So I ran a &lt;strong&gt;blind backtest&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsg02bl3y5yiw7l4myemz.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%2Fsg02bl3y5yiw7l4myemz.png" alt="The backtest: 45 real Week 3 entries, judged blind" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I picked &lt;strong&gt;45 real Week 3 entries&lt;/strong&gt;: 10 that won a prize and 35 that didn't (mine included).&lt;/li&gt;
&lt;li&gt;Judge Fangs scored all 45 &lt;strong&gt;without being told which ones won&lt;/strong&gt;. The "what winners have in common" step was built from &lt;em&gt;other&lt;/em&gt; winning posts, so he couldn't peek at the answers.&lt;/li&gt;
&lt;li&gt;Then I revealed the real results.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;9 of the 10 real winners&lt;/strong&gt; landed in his top 10.&lt;/li&gt;
&lt;li&gt;Average score of winners: &lt;strong&gt;96&lt;/strong&gt;. Non-winners: &lt;strong&gt;64&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&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/Raga-V" rel="noopener noreferrer"&gt;
        Raga-V
      &lt;/a&gt; / &lt;a href="https://github.com/Raga-V/judge-fangs" rel="noopener noreferrer"&gt;
        judge-fangs
      &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;Judge Fangs&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Your hackathon companion, from idea to verdict.&lt;/strong&gt; A strict, funny, 3,000-year-old vampire judge who has sat on every hackathon jury since the fall of Rome, and who now sits beside you through the whole hackathon.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"I have watched empires fall with more structure than your README. Three fixes. Then we shall speak again."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Open a &lt;strong&gt;case file&lt;/strong&gt; for each hackathon you enter: paste its URL or just type its name. The Count digs up the theme, the judging criteria in order of weight, the prize categories, the deadline and what past winners had in common. Then each case follows the hackathon timeline:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tab&lt;/th&gt;
&lt;th&gt;When&lt;/th&gt;
&lt;th&gt;What Fangs does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Brief&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;before&lt;/td&gt;
&lt;td&gt;The case file: the theme in one line, weighted criteria, prize categories, a deadline countdown, "what winners usually have", and the sources he read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ideate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;before&lt;/td&gt;
&lt;td&gt;Judges up to 5 ideas on originality, theme fit, buildability before the deadline&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Raga-V/judge-fangs" 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;h3&gt;
  
  
  Three steps: dig, check, judge
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fawxr9tggoatwywm76kai.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%2Fawxr9tggoatwywm76kai.png" alt="Dig, check, judge. Only the last step uses AI." width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Dig.&lt;/strong&gt; The server fetches the challenge page and the winners announcement through the public DEV API, and your repo through the GitHub API. If you don't have the winners post, &lt;strong&gt;SerpApi&lt;/strong&gt; (a search API) finds it. Gemma then extracts the judging criteria in order of weight, plus the patterns the winners shared. For Week 3, those included things like &lt;em&gt;a number in the title&lt;/em&gt; and &lt;em&gt;one measured test&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Check.&lt;/strong&gt; This step is plain Python, with no AI. It collects hard facts the model can't argue with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did the post claim "Best Use of Sentry"? Then is there a Sentry package in the repo's dependencies, or a Sentry import in the code? Each claim is marked &lt;strong&gt;backed by code&lt;/strong&gt;, &lt;strong&gt;mentioned only&lt;/strong&gt; or &lt;strong&gt;not found&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Is there a number in the title? A demo link? A video? How long is it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Judge.&lt;/strong&gt; One call to Gemma, with the criteria, the winners' patterns, the evidence and your submission. It must answer in a strict JSON format (fixed fields that code can read): a score from 0 to 10 per criterion, a one-line verdict, and an &lt;strong&gt;exact quote from your post as evidence&lt;/strong&gt;. Then come the reasons you'd lose, 3 fixes, a better title and a better opening.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guard rails: the judge is not allowed to lie
&lt;/h3&gt;

&lt;p&gt;AI models make things up. So, like a real court, Judge Fangs needs evidence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every quote is checked.&lt;/strong&gt; If the "evidence" isn't actually in your post, that score is marked &lt;em&gt;unsupported&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code overrules the model.&lt;/strong&gt; If Gemma says you used a partner technology but the repo check found nothing, the verdict says so: &lt;em&gt;"The code check overruled the model."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scores are capped and validated&lt;/strong&gt; before they reach the screen. Broken JSON gets one retry with the error explained.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The ghost in your machine: the desktop companion
&lt;/h3&gt;

&lt;p&gt;The desktop app is a small Electron app (Electron lets you build desktop apps with web code). Here's what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Press &lt;strong&gt;Ctrl+Shift+J&lt;/strong&gt; and a transparent window appears over everything, with the pixel vampire walking along the bottom of your screen.&lt;/li&gt;
&lt;li&gt;He takes a screenshot, and &lt;strong&gt;shows it to you first&lt;/strong&gt;. Nothing is sent until you press &lt;strong&gt;"Judge this"&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The screenshot goes to the same server. Gemma (which can read images) works out what you're looking at, whether it's a post, an email, an idea or code, and runs the same dig, check and judge steps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's never continuous, never saved, and the image is deleted right after judging.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture: nothing runs on your laptop
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsmds2azdmdotv3gni6rr.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%2Fsmds2azdmdotv3gni6rr.png" alt="Architecture: web app and desktop companion, FastAPI on Render, Gemma on a separate server" width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last week, judges had to install Ollama to try my app. That was a mistake, so this time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;brain&lt;/strong&gt; is a large Gemma model, &lt;strong&gt;gemma-4-31b-it&lt;/strong&gt;, hosted on a separate server. I call it through a standard, OpenAI-compatible API, so switching to another host, or to my own server, is one setting.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;courthouse&lt;/strong&gt; is a FastAPI service on Render that holds every key.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;face&lt;/strong&gt; is a React app on a Render static site.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your browser never sees a key. If the keys or the daily quota run out, he switches to demo mode: &lt;em&gt;"The tribunal is adjourned until moonrise."&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How each partner technology is used
&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%2F54ijxxh6vbz7zhf7bxbj.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%2F54ijxxh6vbz7zhf7bxbj.png" alt="Best Use of Gemma: the brain" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; Gemma is the judge's mind. It reads posts, repos and screenshots, extracts the rules of each hackathon, and writes every verdict.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Three jobs, one model:&lt;/strong&gt; reading the challenge (extracting the criteria), reading your screen (vision), and judging (strict JSON with evidence quotes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A large open-weight model&lt;/strong&gt; on a separate server, because judging long posts needs a big model. But it's still open, so anyone can host the same weights themselves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It never has the final word.&lt;/strong&gt; Code checks every quote and every partner claim.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpsh0q1ugsb6ipnu2blca.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%2Fpsh0q1ugsb6ipnu2blca.png" alt="Best Use of Render: the courthouse" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; Render is where Judge Fangs lives, so nobody has to install anything.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Two services, one Blueprint&lt;/strong&gt; (&lt;code&gt;render.yaml&lt;/code&gt;): a FastAPI &lt;strong&gt;web service&lt;/strong&gt; holding the keys, and a &lt;strong&gt;static site&lt;/strong&gt; for the React app. One click deploys both.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built for strangers on the internet:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;per-visitor rate limits and a daily cap, so nobody drains my API credits&lt;/li&gt;
&lt;li&gt;request size caps&lt;/li&gt;
&lt;li&gt;an allowlist, so the server only ever fetches from DEV, GitHub and SerpApi, never private addresses&lt;/li&gt;
&lt;li&gt;a health check&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo mode&lt;/strong&gt; if a key is missing or the quota runs out, so judges always see something work.&lt;/li&gt;
&lt;li&gt;The digging log ("Reading 3 winning entries…") streams live from Render to your screen.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdppyj06w9xc097rwg15m.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%2Fdppyj06w9xc097rwg15m.png" alt="Best Use of ElevenLabs: the voice" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; Judge Fangs speaks. You haven't really been judged until a vampire says "forty-one out of a hundred" to your face.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;eleven_v3&lt;/code&gt; with audio tags (stage directions in square brackets) such as &lt;code&gt;[clears throat]&lt;/code&gt; and &lt;code&gt;[coldly]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Cached by text, so the same sentence is never paid for twice. Only lines the server itself wrote can be voiced.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft3kfrisj6bmp1ytu7rl8.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%2Ft3kfrisj6bmp1ytu7rl8.png" alt="Best Use of Sentry: the court record" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; Sentry keeps the court record. For every judgement, I can see each step he took, how long it took and how hard the model worked, without Sentry ever seeing your text.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One trace per judgement&lt;/strong&gt;, using Sentry's AI agent span types:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gen_ai.invoke_agent&lt;/code&gt; for the whole judgement&lt;/li&gt;
&lt;li&gt;a child span for each fetch (DEV, GitHub, winners, search)&lt;/li&gt;
&lt;li&gt;a span for the code checks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gen_ai.chat&lt;/code&gt; for each Gemma call, with tokens, timing and retries&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lengths, labels and timings only, never your words or screenshots.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6cxwdw1eukvh0qc7oa78.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%2F6cxwdw1eukvh0qc7oa78.png" alt="Best Use of SerpApi: the detective" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; you don't need to know where the winners post is. Name the hackathon, and SerpApi finds it, so Judge Fangs can study what won.&lt;/p&gt;

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

&lt;p&gt;Hackathon judging is a black box. You submit, you wait, you lose, and you never find out why.&lt;/p&gt;

&lt;p&gt;Judge Fangs is the opposite of a black box:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The rules he judges by are in the open:&lt;/strong&gt; the scoring is in the code, and the evidence is on the screen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model is open-weight.&lt;/strong&gt; Anyone can run the same judge on their own server, change his rubric, or make him kinder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The code is open.&lt;/strong&gt; If you think he's wrong, you can see exactly why he decided what he did, and fix him.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A closed AI that grades you with no reasons would just be another black box. An open one can show its working, and that's the whole point of a judge.&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%2F1calunbqhprcyiyp7jq0.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%2F1calunbqhprcyiyp7jq0.png" alt="What goes where" width="799" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest Limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;He's a model, not the real jury.&lt;/strong&gt; The backtest shows how often his taste matches theirs (9 of 10), not that he can predict prizes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;He's harsh by design.&lt;/strong&gt; Under the theatre, the fixes are meant to be kind and specific.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The desktop companion&lt;/strong&gt; is Windows-first and needs installing. The web app is the one anyone can try.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your submission text goes to the hosted model provider&lt;/strong&gt; in order to be judged. Nothing is stored.&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; a large hosted Gemma model reads challenge pages, posts and screenshots, extracts each hackathon's rules, and judges with evidence quotes that code verifies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render:&lt;/strong&gt; a FastAPI web service plus a React static site in one Blueprint, with keys kept server-side, rate limits, an SSRF-safe allowlist (the server can't be tricked into fetching private addresses), streaming and a demo-mode fallback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs:&lt;/strong&gt; Judge Fangs reads his sentence aloud with &lt;code&gt;eleven_v3&lt;/code&gt; audio tags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Sentry Agent Tracing:&lt;/strong&gt; one AI agent trace per judgement, with spans for digging, code checks and each Gemma call, and no private text sent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of SerpApi:&lt;/strong&gt; finds the winners announcement for any hackathon you name.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Raga Vinjanampati: three weeks, three projects, zero wins, and one vampire who finally told me why. Objection noted.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>I built an AI couch potato that tells me which chores to skip. My mom agrees with it.</title>
      <dc:creator>Raga Vinjanampati</dc:creator>
      <pubDate>Mon, 26 Oct 2026 02:26:57 +0000</pubDate>
      <link>https://dev.to/raga_vinjanampati/i-built-an-ai-couch-potato-that-tells-me-which-chores-to-skip-my-mom-agrees-with-it-3nj7</link>
      <guid>https://dev.to/raga_vinjanampati/i-built-an-ai-couch-potato-that-tells-me-which-chores-to-skip-my-mom-agrees-with-it-3nj7</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;p&gt;Every day I have the same argument with myself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Do I &lt;em&gt;really&lt;/em&gt; need to go to the 8 AM lecture?&lt;br&gt;
&lt;strong&gt;Also me:&lt;/strong&gt; You're going to regret this.&lt;br&gt;
&lt;strong&gt;Me:&lt;/strong&gt; I'll regret it &lt;em&gt;later&lt;/em&gt;. Later is a problem for future me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I hired a professional. He's a potato. He lives on a couch. He wears sunglasses indoors. His name is &lt;strong&gt;Lazy&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;To test him, I asked Lazy and my mom the same questions about my own chores. Lazy told me to &lt;strong&gt;skip a date&lt;/strong&gt; and &lt;strong&gt;clean the fridge&lt;/strong&gt;. My mom said exactly the same thing. I have never felt so outnumbered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In 30 seconds:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it is:&lt;/strong&gt; tell Lazy what you're avoiding, answer up to 3 taps, and get one verdict: skip it, do the lazy minimum, do it later, or yes, do it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The trick:&lt;/strong&gt; an open AI model (Gemma 3) runs &lt;em&gt;on your laptop&lt;/em&gt; and only collects the facts. About 200 lines of plain JavaScript make the actual decision, so the AI can't talk you out of paying a bill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The proof:&lt;/strong&gt; my mom and Lazy answered the same questions. I agreed with Lazy 7 times out of 10.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The stack:&lt;/strong&gt; Gemma 3 + Ollama, Render, ElevenLabs, Sentry, TabPFN, GitHub Actions + Copilot. Each one has exactly one job.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;Do I Need to Do This?&lt;/strong&gt; is a web app for people who are tired of deciding. You type the task you're avoiding. Lazy asks you up to &lt;strong&gt;three quick questions&lt;/strong&gt;, and you answer with a tap. Then he gives you &lt;strong&gt;one honest verdict&lt;/strong&gt;:&lt;/p&gt;

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

&lt;p&gt;The twist: &lt;strong&gt;Lazy is not allowed to let you off the hook for the important stuff.&lt;/strong&gt; Health, money, official paperwork and anything graded can &lt;em&gt;never&lt;/em&gt; get "Skip it". Lazy is lazy, not irresponsible.&lt;/p&gt;

&lt;p&gt;And the part I'm proudest of: &lt;strong&gt;the AI doesn't pick the verdict.&lt;/strong&gt; Gemma, an open model running on your own laptop, reads, asks and takes notes. A small file of plain JavaScript rules makes the final call. More on why below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Meet Lazy (a short, cute video)
&lt;/h3&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/uRtX8jOMjpw" width="710" height="399"&gt;
  &lt;/iframe&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%2F8oz5uhwx717vj652x7ht.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%2F8oz5uhwx717vj652x7ht.png" alt="Lazy's 7 Moods" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://raga-v.github.io/do-i-need-to-do-this/" rel="noopener noreferrer"&gt;raga-v.github.io/do-i-need-to-do-this&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The AI runs on &lt;em&gt;your&lt;/em&gt; laptop, so you'll need &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;, a free app for running AI models locally, with the &lt;code&gt;gemma3:4b&lt;/code&gt; model downloaded. The app's &lt;strong&gt;AI setup&lt;/strong&gt; screen gives you the exact one-line command to copy.&lt;/p&gt;

&lt;p&gt;What you can do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ask about one task.&lt;/strong&gt; "Go to the 8 AM lecture tomorrow", "Pay the electricity bill", "Reply to the group chat", "Iron my shirt".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add a photo.&lt;/strong&gt; A timetable, a notice, a screenshot. Lazy reads it before he asks anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan my lazy day.&lt;/strong&gt; Save your timetable once, and Lazy sorts your whole day into &lt;em&gt;Must do · Lazy minimum · Skip · Later&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hear the verdict.&lt;/strong&gt; Lazy delivers it like a tired judge: &lt;em&gt;"[sighs] Skip it. … Court is adjourned."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff: Mom vs. Lazy
&lt;/h2&gt;

&lt;p&gt;Anyone can say their app works. So I sat my mom on our (non-purple) sofa, asked her the questions I'd normally overthink, filmed her answers, and then asked Lazy the same questions on my laptop. Two judges, my chores.&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%2Fortmyuxw3giea4bf1hka.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%2Fortmyuxw3giea4bf1hka.png" alt="Mom vs. Lazy: 13 tasks judged, I agreed with Lazy 7 out of 10 times, 5.1 hours back this week" width="800" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Straight from the app's History screen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;13 tasks judged.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I agreed with Lazy 7 out of 10 times&lt;/strong&gt; (I answered "Would you have decided the same?" on 10 of them).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5.1 hours back this week.&lt;/strong&gt; That's the sum of Gemma's own effort estimates for everything Lazy said to skip or shrink, not a stopwatch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Highlights from the tape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Do you think I should reply in the family group chat?"&lt;/strong&gt; Mom: &lt;em&gt;"Why didn't you reply yet?"&lt;/em&gt; Lazy, slightly more relaxed: &lt;strong&gt;Do the lazy minimum.&lt;/strong&gt; Just send a quick "okay" message. About 2 minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Do you think I should go on a date with a guy I never met before?"&lt;/strong&gt; Mom: &lt;em&gt;"No. Never. And ever."&lt;/em&gt; Lazy asked one question, &lt;em&gt;"Would letting him down be bad?"&lt;/em&gt;, and then: &lt;strong&gt;Skip it.&lt;/strong&gt; &lt;em&gt;"Since you've never met him, a simple decline won't cause any issues."&lt;/em&gt; Mom and the potato, united.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Do you think I should clean the fridge before Diwali?"&lt;/strong&gt; Mom: &lt;em&gt;"Do you think the sky is blue? Obviously you have to."&lt;/em&gt; Lazy jumped off the couch: &lt;strong&gt;Yes, do it.&lt;/strong&gt; &lt;em&gt;"Your mum will probably get annoyed if you don't clean the fridge."&lt;/em&gt; He knows her. Judged by Gemma in 83.7 seconds, on my laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where I disagreed: "Do you think I should do my little sister's assignment?"&lt;/strong&gt; I would have skipped it. Lazy said &lt;strong&gt;Do the lazy minimum.&lt;/strong&gt; That's not Gemma being wrong. It's my own safety rule: "assignment" is on the graded-work list, and graded work can never be skipped. Lazy refused to help me be a bad sibling. Fair.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjjspcfrjxolpek27zjni.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%2Fjjspcfrjxolpek27zjni.png" alt="History screen: 5.1 h saved, 70% agree with AI, 13 tasks judged" width="800" height="1581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/zs4pVvtphqI" width="710" height="399"&gt;
  &lt;/iframe&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/Raga-V" rel="noopener noreferrer"&gt;
        Raga-V
      &lt;/a&gt; / &lt;a href="https://github.com/Raga-V/do-i-need-to-do-this" rel="noopener noreferrer"&gt;
        do-i-need-to-do-this
      &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;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/hero.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Fhero.png" alt="My mom vs. a couch potato: who decides my chores? I asked my mom and Lazy, an AI couch potato on my laptop, the same questions about what I can skip. They agreed more than I'd like. Lazy: Skip it. Mom: Never."&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Do I Need to Do This?&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;a href="https://github.com/Raga-V/do-i-need-to-do-this/actions/workflows/deploy.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/Raga-V/do-i-need-to-do-this/actions/workflows/deploy.yml/badge.svg" alt="CI and Pages"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/a169352ab663f6569ce2d8c5b427d8b70b8bc19482874785d4c4122b0113710e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f41492d47656d6d612532303325323034422532306f6e253230796f75722532306c6170746f702d374336434632"&gt;&lt;img src="https://camo.githubusercontent.com/a169352ab663f6569ce2d8c5b427d8b70b8bc19482874785d4c4122b0113710e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f41492d47656d6d612532303325323034422532306f6e253230796f75722532306c6170746f702d374336434632" alt="Gemma 3 4B on your laptop"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/3ba2aed93a34c7ca817efb638282f869c6749fe13cc55bf037153ee9dfd1fca2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7365727665722d7a65726f253230646570656e64656e636965732d314431423338"&gt;&lt;img src="https://camo.githubusercontent.com/3ba2aed93a34c7ca817efb638282f869c6749fe13cc55bf037153ee9dfd1fca2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7365727665722d7a65726f253230646570656e64656e636965732d314431423338" alt="Zero-dependency server"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/1e41408f4875130064fa87fef3a3bf3da45aaaadcaaf34631162160c5c5982b8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d304538413546"&gt;&lt;img src="https://camo.githubusercontent.com/1e41408f4875130064fa87fef3a3bf3da45aaaadcaaf34631162160c5c5982b8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d304538413546" alt="MIT license"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;b&gt;Tell it what you're avoiding. Gemma 3 asks a few questions on your laptop. Plain rules give an honest verdict.&lt;/b&gt;&lt;br&gt;
  &lt;a href="https://raga-v.github.io/do-i-need-to-do-this/" rel="nofollow noopener noreferrer"&gt;&lt;b&gt;Try it live&lt;/b&gt;&lt;/a&gt; · &lt;a href="https://github.com/Raga-V/do-i-need-to-do-this#run-it" rel="noopener noreferrer"&gt;Run it&lt;/a&gt; · &lt;a href="https://github.com/Raga-V/do-i-need-to-do-this#how-it-decides" rel="noopener noreferrer"&gt;How it decides&lt;/a&gt; · &lt;a href="https://github.com/Raga-V/do-i-need-to-do-this#privacy" rel="noopener noreferrer"&gt;Privacy&lt;/a&gt; · &lt;a href="https://github.com/Raga-V/do-i-need-to-do-this#partner-technologies" rel="noopener noreferrer"&gt;Partners&lt;/a&gt;
&lt;/p&gt;




&lt;p&gt;Type the task you're avoiding: &lt;em&gt;"Go to the 8 AM lecture tomorrow"&lt;/em&gt;, &lt;em&gt;"Pay the electricity bill"&lt;/em&gt;. Optionally add a line of context or a photo of a timetable, notice or screenshot. &lt;strong&gt;Gemma 3 runs on your own laptop&lt;/strong&gt;, asks up to three tap-to-answer questions, and then the app hands down one of five verdicts.&lt;/p&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/five-verdicts.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Ffive-verdicts.png" alt="The five verdicts: Skip it (asleep, snoring), Do the lazy minimum (sipping coffee), Do it later (holding a calendar), Yes, do it (sunglasses flying), Not sure yet (peering over his shades). Health, money, official paperwork and anything graded can never get Skip it."&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Built for the DEV Hacktoberfest Open-Source AI Challenge, Week 3: &lt;em&gt;Slow and Steady&lt;/em&gt; (build something with open-source AI that rewards laziness).&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Meet Lazy&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;table&gt;

  &lt;tbody&gt;

&lt;tr&gt;

    &lt;td&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/lazy-chill.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Flazy-chill.svg" width="110" alt="Lazy chilling on the couch in sunglasses"&gt;&lt;/a&gt;&lt;br&gt;&lt;b&gt;Home&lt;/b&gt;&lt;br&gt;chilling&lt;br&gt;
&lt;/td&gt;

    &lt;td&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/lazy-thinking.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Flazy-thinking.svg" width="110" alt="Lazy thinking, with a question bubble"&gt;&lt;/a&gt;&lt;br&gt;&lt;b&gt;Thinking&lt;/b&gt;&lt;br&gt;while Gemma works&lt;br&gt;
&lt;/td&gt;

    &lt;td&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/lazy-skip.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Flazy-skip.svg" width="110" alt="Lazy asleep, snoring"&gt;&lt;/a&gt;&lt;br&gt;&lt;b&gt;Skip it&lt;/b&gt;&lt;br&gt;asleep&lt;br&gt;
&lt;/td&gt;

    &lt;td&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/lazy-min.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Flazy-min.svg" width="110" alt="Lazy sipping coffee"&gt;&lt;/a&gt;&lt;br&gt;&lt;b&gt;Lazy minimum&lt;/b&gt;&lt;br&gt;coffee&lt;br&gt;
&lt;/td&gt;

    &lt;td&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/lazy-later.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Flazy-later.svg" width="110" alt="Lazy winking with a calendar"&gt;&lt;/a&gt;&lt;br&gt;&lt;b&gt;Later&lt;/b&gt;&lt;br&gt;calendar&lt;br&gt;
&lt;/td&gt;

    &lt;td&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/lazy-do.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Flazy-do.svg" width="110" alt="Lazy wide-eyed and jumping, sunglasses flying"&gt;&lt;/a&gt;&lt;br&gt;&lt;b&gt;Yes, do it&lt;/b&gt;&lt;br&gt;jumping&lt;br&gt;
&lt;/td&gt;

    &lt;td&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/Raga-V/do-i-need-to-do-this/docs/images/lazy-unsure.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRaga-V%2Fdo-i-need-to-do-this%2FHEAD%2Fdocs%2Fimages%2Flazy-unsure.svg" width="110" alt="Lazy puzzled, peering over his shades"&gt;&lt;/a&gt;&lt;br&gt;&lt;b&gt;Not sure&lt;/b&gt;&lt;br&gt;puzzled&lt;br&gt;
&lt;/td&gt;

  &lt;/tr&gt;

&lt;/tbody&gt;

&lt;/table&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lazy&lt;/strong&gt; is a couch potato in sunglasses, drawn entirely…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Raga-V/do-i-need-to-do-this" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


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

&lt;h3&gt;
  
  
  A 20-second jargon decoder
&lt;/h3&gt;

&lt;p&gt;You don't need to be an engineer to follow the rest of this post. These are the only terms that matter:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;What it means here&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gemma 3 4B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An open AI model from Google. "4B" means 4 billion parameters: small enough to run on a normal laptop.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ollama&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A free app that runs AI models on your own computer, like a media player for models.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A simple, strict text format for data, made of &lt;code&gt;"name": value&lt;/code&gt; pairs that code can read reliably.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Schema&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The fixed list of fields the JSON &lt;em&gt;must&lt;/em&gt; have. Anything else gets rejected.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;decide()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The JavaScript function, in the file &lt;code&gt;public/decide.js&lt;/code&gt;, that picks every verdict. No AI inside.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Token&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A chunk of text, roughly ¾ of a word. Models read and write in tokens, so token counts measure how much work the AI did.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A password that lets an app use a paid online service (like ElevenLabs' voices).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The one rule: the AI asks, the code decides
&lt;/h3&gt;

&lt;p&gt;My first instinct was to ask Gemma "should I skip this?" and show whatever it said. That's a bad idea. A small model is great at &lt;em&gt;reading&lt;/em&gt; and &lt;em&gt;asking&lt;/em&gt;, and &lt;strong&gt;terrible at being consistent.&lt;/strong&gt; Ask it the same thing twice and you get two different moods. You don't want a moody judge deciding whether you pay your electricity bill.&lt;/p&gt;

&lt;p&gt;So I split the job in two. Here's where everything runs:&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%2Fxfch3sv9ii51pv21s8tx.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%2Fxfch3sv9ii51pv21s8tx.png" alt="System architecture: the browser app, Ollama and decide() run on your laptop; Render holds the API keys; ElevenLabs, TabPFN and Sentry only get labels" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How to read this diagram: everything in the &lt;strong&gt;purple box&lt;/strong&gt; happens on your laptop, and that includes the AI. The &lt;strong&gt;white box&lt;/strong&gt; is a small server on Render whose only job is holding the API keys. The &lt;strong&gt;orange box&lt;/strong&gt; is the online services. The arrows show the only things that ever reach them: one line of text to speak, and a few labels.&lt;/p&gt;

&lt;p&gt;And here's one run, from your question to Lazy's gavel:&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%2Fuavrhft0an1mthln4sk8.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%2Fuavrhft0an1mthln4sk8.png" alt="Sequence diagram: you ask, Gemma asks up to 3 questions, Gemma writes JSON facts, decide() picks the verdict, ElevenLabs voices it, TabPFN learns from your answer" width="800" height="641"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read it top to bottom. Each numbered arrow is one message passing between you, Gemma, the rules and the online services. In words:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Gemma reads.&lt;/strong&gt; If you add a photo (say, your timetable), Gemma copies down &lt;em&gt;only what it can actually see&lt;/em&gt;. Anything unreadable is marked &lt;code&gt;[?]&lt;/code&gt; instead of guessed, and you can correct what it read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma asks.&lt;/strong&gt; Up to 3 questions, each with 2–4 answers you tap, and only about what it doesn't already know.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma writes down facts, not opinions.&lt;/strong&gt; Instead of chatting, it has to fill in a form, as JSON. Ollama's &lt;code&gt;format&lt;/code&gt; option forces the answer to match the schema, so Gemma can't add or skip fields. For "clean the fridge", the form looks something like this:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;category&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chores&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// what kind of task (chores, money, health, exam...)&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consequence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;annoying&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// what happens if you skip it: nothing, minor, annoying, serious or severe&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;affects_others&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// does skipping it let someone else down?&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;can_be_undone_later&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// can you fix it later if you skip it now?&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;effort_minutes&lt;/span&gt;&lt;span class="dl"&gt;"&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;// how long the whole task takes&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lazy_minimum&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Throw out anything expired&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// the smallest version that keeps you out of trouble&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lazy_minimum_minutes&lt;/span&gt;&lt;span class="dl"&gt;"&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="c1"&gt;// how long that smallest version takes&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confidence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;              &lt;span class="c1"&gt;// how sure Gemma is about all of the above (0 to 1)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(An example of the shape, not a real log. The comments are mine, for this post.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;4. &lt;strong&gt;Plain JavaScript decides.&lt;/strong&gt; The &lt;code&gt;decide()&lt;/code&gt; function reads those fields and picks the verdict. It's about 200 lines with no AI in it, and the same file runs in the app and in the automated tests. That means every rule is checked before any code goes live.&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%2Fda86ev6yuqvmye3wx0ju.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%2Fda86ev6yuqvmye3wx0ju.png" alt="The rules inside decide(): low confidence gives Not sure yet; the consequence picks the verdict; a safety override stops protected tasks from being skipped" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The rulebook in three steps: &lt;strong&gt;(1)&lt;/strong&gt; if Gemma is less than 50% sure, Lazy says "Not sure yet". &lt;strong&gt;(2)&lt;/strong&gt; Otherwise, how bad skipping would be picks the verdict. For example, "minor" and only affects you gives Skip it. &lt;strong&gt;(3)&lt;/strong&gt; Finally, a safety check: if the result is Skip it but the task involves health, money, legal paperwork or graded work, the verdict is upgraded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gemma tried to cheat. The code caught it.
&lt;/h3&gt;

&lt;p&gt;A small model running on a laptop makes mistakes. Instead of hoping a better prompt would fix them, I added &lt;strong&gt;guard rails in code&lt;/strong&gt;: small checks that run on Gemma's answer before the rules ever see it. Every rail exists because of a real mistake I saw in testing:&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%2Fg4bte7gu5b4ezf19wt72.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%2Fg4bte7gu5b4ezf19wt72.png" alt="Six guard rails between Gemma's raw answer and decide()" width="799" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It filed "Pay the electricity bill" under "other".&lt;/strong&gt; Now, if the task's own words mention a bill, payment, doctor, exam or passport, it's treated as protected, whatever category Gemma picked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It "quoted" things I never said.&lt;/strong&gt; Gemma is allowed to skip a question if I've already answered it, but it has to quote my exact words as proof, and the code checks the quote really is in what I typed. It once invented &lt;em&gt;"They'll cut off the power."&lt;/em&gt; Nobody said that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It told someone to skip the laundry because their attendance was high.&lt;/strong&gt; Lazy now only shows Gemma the "About me" notes on the same topic as the task. Your attendance has nothing to do with your socks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Its maths was creative.&lt;/strong&gt; In one test it reasoned that 88% attendance minus one class is below 75%. The rules only read the form fields, not Gemma's reasoning, and the verdict card shows Gemma's working so you can catch moments like this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If Gemma is less than 50% sure, Lazy says "Not sure yet".&lt;/strong&gt; He'd rather ask than guess.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time the code overrules Gemma, the verdict card says so: &lt;strong&gt;"The app overruled Gemma."&lt;/strong&gt; No secret edits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lazy remembers you (without spying on you)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory.&lt;/strong&gt; After each verdict, Gemma suggests up to 3 &lt;em&gt;lasting&lt;/em&gt; facts about you ("College requires 75% attendance"). The code throws away anything you didn't actually say, one-off details and duplicates. You can edit or delete any of them in Settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timetable.&lt;/strong&gt; Upload a photo once. If it's a clean grid, plain code turns it into a timetable instantly. Messier photos go to Gemma, and any row it wasn't sure about gets a &lt;strong&gt;"check this"&lt;/strong&gt; badge instead of a guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan my lazy day.&lt;/strong&gt; Gemma fills in one form for every class or task on today's timetable, in a single request, and then the &lt;em&gt;same&lt;/em&gt; &lt;code&gt;decide()&lt;/code&gt; rules judge each one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this is saved in your own browser's storage (&lt;code&gt;localStorage&lt;/code&gt;) and only ever sent to Gemma, on your own laptop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Small things that make it feel alive
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lazy is drawn entirely in code.&lt;/strong&gt; He's an SVG, a drawing written as code, so there are no image files. He breathes, his Zzz float up, and he bounces when he panics. The animations switch off if you've asked your device to reduce motion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Funny sounds,&lt;/strong&gt; generated live in the browser with the Web Audio API (the browser's built-in synthesizer), so there are no audio files either: a &lt;em&gt;snore&lt;/em&gt; for skip, a coffee &lt;em&gt;slurp&lt;/em&gt; for the lazy minimum, a &lt;em&gt;tick-tock&lt;/em&gt; for later, a panicked &lt;em&gt;boing&lt;/em&gt; for "do it", and a &lt;em&gt;flump&lt;/em&gt; as Lazy lands on the couch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What I didn't ship: a microphone.&lt;/strong&gt; I wanted local speech-to-text with Whisper, an open speech-recognition model, but couldn't build and test it in time. The browser's built-in speech recognition sends your audio to Google, so I left it out rather than break the privacy promise.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  How each partner technology is used
&lt;/h2&gt;

&lt;p&gt;Every partner has exactly one job in Lazy's household. Each section starts with the plain-English version, then the details for the curious.&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%2Fqbt6c1g4f4sxvuyhlv9j.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%2Fqbt6c1g4f4sxvuyhlv9j.png" alt="Best Use of Gemma 3: the brain" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; Gemma is the part that reads and listens. It runs on your own laptop through Ollama, so it costs nothing per question and your tasks never leave home.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vision:&lt;/strong&gt; reads timetable photos, notices and screenshots, copying down only what's visible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conversation:&lt;/strong&gt; decides which follow-up questions to ask, and writes the tap-to-answer options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filling in the form:&lt;/strong&gt; returns the JSON facts shown above. If the JSON comes back broken, the app retries once and tells Gemma exactly what was wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory, timetables and planning:&lt;/strong&gt; each is its own small, separate request with its own form, and a cap on how much Gemma may write.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemma &lt;strong&gt;never picks the verdict&lt;/strong&gt;, and that's what makes it safe to give a small model this job. Each verdict card is open about the work: how long Gemma took on your laptop, how many tokens it read and wrote, its speed, and the full table of facts it filled in.&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%2Fchcr6athu76blw0xc8w5.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%2Fchcr6athu76blw0xc8w5.png" alt="Best Use of Render: the house" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; Lazy's brain lives on your laptop, but his voice and his gut feeling need secret API keys. Secrets can't live in a web page, where anyone could read them. So they live on a small server at Render, which uses them on Lazy's behalf.&lt;/p&gt;

&lt;p&gt;That server is one file, &lt;code&gt;server.js&lt;/code&gt;, with zero extra code libraries. Render runs it as a &lt;strong&gt;web service&lt;/strong&gt;: a program that's always on and answers requests. Render calls a config file that sets everything up a &lt;strong&gt;Blueprint&lt;/strong&gt;, and mine is &lt;code&gt;render.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;web&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;do-i-need-to-do-this&lt;/span&gt;
    &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node&lt;/span&gt;
    &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;singapore&lt;/span&gt;          &lt;span class="c1"&gt;# the closest Render region to users in India&lt;/span&gt;
    &lt;span class="na"&gt;buildCommand&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;       &lt;span class="c1"&gt;# install, exactly as locked in package-lock.json&lt;/span&gt;
    &lt;span class="na"&gt;startCommand&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node server.js&lt;/span&gt;
    &lt;span class="na"&gt;healthCheckPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/healthz&lt;/span&gt;  &lt;span class="c1"&gt;# Render pings this page to check the server is alive&lt;/span&gt;
    &lt;span class="na"&gt;autoDeploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;           &lt;span class="c1"&gt;# every push to GitHub redeploys automatically&lt;/span&gt;
    &lt;span class="na"&gt;buildFilter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;               &lt;span class="c1"&gt;# ...unless only the README or tests changed&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;public/**&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;server.js&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;tabpfn.js&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;package.json&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;package-lock.json&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;envVars&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;                   &lt;span class="c1"&gt;# the secret keys&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ELEVENLABS_API_KEY&lt;/span&gt;
        &lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;            &lt;span class="c1"&gt;# typed into Render's dashboard, never written in the code&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SENTRY_DSN&lt;/span&gt;
        &lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TABPFN_TOKEN&lt;/span&gt;
        &lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(Trimmed for the post. The full file is in the repo.)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One-click deploy:&lt;/strong&gt; anyone can copy the repo and get the same server with one click.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets stay out of the code:&lt;/strong&gt; every key lives only in Render's dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe on the open internet:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Files are compressed before they're sent (gzip), so the app loads faster.&lt;/li&gt;
&lt;li&gt;Each visitor gets a limited number of requests (rate limiting), so nobody can drain my API credits.&lt;/li&gt;
&lt;li&gt;Anything sent to the server is capped at 16 KB, so a photo physically can't be uploaded. That's a privacy promise you can check in the code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You always know what's live:&lt;/strong&gt; the app's footer shows exactly which version is running. It reads Render's &lt;code&gt;RENDER_GIT_COMMIT&lt;/code&gt; setting, the ID of the code commit. Render also checks &lt;code&gt;/healthz&lt;/code&gt; before it switches visitors to a new version.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdd0d7kt98rglhijyxh0.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%2Fgdd0d7kt98rglhijyxh0.png" alt="Best Use of ElevenLabs: the voice" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; Lazy talks. He reads you his questions, bangs a gavel, and announces the verdict like a very tired judge.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A voice with a personality.&lt;/strong&gt; When you tap "Hear the verdict", the app asks the server (at &lt;code&gt;/api/speak&lt;/code&gt;) to voice one line. It uses ElevenLabs' newest model, &lt;code&gt;eleven_v3&lt;/code&gt;, which understands &lt;strong&gt;audio tags&lt;/strong&gt;: stage directions in square brackets that change how the line is performed. The server adds them per verdict: &lt;code&gt;[sighs] Skip it. … [laughs] Court is adjourned.&lt;/code&gt; or &lt;code&gt;[clears throat] Yes, do it.&lt;/code&gt; If v3 is unavailable, it falls back to the older &lt;code&gt;eleven_multilingual_v2&lt;/code&gt; voice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sound effects, generated by ElevenLabs:&lt;/strong&gt; a &lt;strong&gt;gavel bang&lt;/strong&gt; before every verdict, and a &lt;strong&gt;snore&lt;/strong&gt; when you poke Lazy. ElevenLabs creates them from a text description. Each is made once when the server starts and then reused, instead of being paid for on every verdict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lazy reads each question aloud,&lt;/strong&gt; so it feels like a conversation, not a form.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It can't be abused as a free voice service.&lt;/strong&gt; The server only voices verdict lines and short questions: one sentence, at most 140 characters, ending in "?", no links. It also gets a stricter request limit.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7no98lknpgaw6uo4cwb2.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%2F7no98lknpgaw6uo4cwb2.png" alt="Best Use of Sentry: the security camera" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; Sentry is a security camera on Gemma's thinking. For every run, I can see which steps Gemma took, how long each one took and how hard it had to work, without Sentry ever seeing what you typed.&lt;/p&gt;

&lt;p&gt;Two Sentry words first. A &lt;strong&gt;trace&lt;/strong&gt; is the full recording of one run. A &lt;strong&gt;span&lt;/strong&gt; is one step inside it, drawn as a bar on a timeline. Each run is one trace that reads like a story: &lt;strong&gt;agent, then Gemma, then Gemma again, then the rules.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm4bf0ixyzcgipjz1a1fo.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%2Fm4bf0ixyzcgipjz1a1fo.png" alt="An illustration of one Sentry trace: invoke_agent containing three gen_ai.chat spans and one execute_tool span" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;I use Sentry's AI agent span types,&lt;/strong&gt; so Sentry knows what each step is:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gen_ai.invoke_agent&lt;/code&gt; is the whole run.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gen_ai.chat&lt;/code&gt; is one call to Gemma. There's one per step: reading the photo, asking questions, filling in the facts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gen_ai.execute_tool&lt;/code&gt; is the rules deciding. I named it &lt;code&gt;decide_verdict&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Each Gemma step records&lt;/strong&gt; which model ran, which step it was, whether it was a retry, how many tokens went in and came out (taken straight from Ollama's own counters), and how long it took.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The rules step records&lt;/strong&gt; the facts that went in and the verdict and rule that came out. A surprising verdict can be traced to the exact rule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broken JSON&lt;/strong&gt; from Gemma is logged as an error, labelled with the step and attempt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When you disagree with the court,&lt;/strong&gt; Sentry records both verdicts and the rule that fired. That's the best signal for tuning the rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy:&lt;/strong&gt; no prompts, replies, photos or task text are ever sent to Sentry. Only lengths and labels.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpd2uuqo37ao2a2jj135e.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%2Fpd2uuqo37ao2a2jj135e.png" alt="A real Sentry trace from my dashboard" width="800" height="226"&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%2F1xflp4n58xvp5z19p1bu.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%2F1xflp4n58xvp5z19p1bu.png" alt="Best Use of TabPFN: the gut feeling" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; the rules give the &lt;em&gt;official&lt;/em&gt; verdict. TabPFN guesses what &lt;em&gt;you&lt;/em&gt; would actually pick, based on your past answers. I disagreed with Lazy 3 times out of 10, and TabPFN is how Lazy learns that about me.&lt;/p&gt;

&lt;p&gt;TabPFN is an AI model built for small tables of data. Most machine learning needs thousands of examples, but TabPFN can learn from a few dozen. One person's verdict history is a few dozen rows at most, so it's the right tool.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it learns from:&lt;/strong&gt; each time you answer "Would you have decided the same?", that verdict becomes one row. Once you have &lt;strong&gt;at least 10 rows&lt;/strong&gt; (with at least two different answers), the app sends TabPFN &lt;strong&gt;six labels per row&lt;/strong&gt;, plus what you actually chose:

&lt;ol&gt;
&lt;li&gt;category&lt;/li&gt;
&lt;li&gt;consequence&lt;/li&gt;
&lt;li&gt;days until the deadline&lt;/li&gt;
&lt;li&gt;whether it affects others&lt;/li&gt;
&lt;li&gt;whether it can be fixed later&lt;/li&gt;
&lt;li&gt;effort in minutes&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No words, ever.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The server checks every value&lt;/strong&gt; against fixed lists and number ranges, and rejects anything else (including free text) before it reaches TabPFN.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The full TabPFN flow:&lt;/strong&gt; upload your history, train on it, then ask for the odds of each verdict. The card shows &lt;em&gt;"Based on your past choices, you'd probably pick: X (NN%)"&lt;/em&gt;, with a bar for each verdict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A "Teach Lazy" progress bar&lt;/strong&gt; in History shows how close you are to 10.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Honest limit:&lt;/strong&gt; with this little data, it's a hint about your habits, not a crystal ball. The rules' verdict always wins.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp4xk8wo4gcpuih8n7fth.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%2Fp4xk8wo4gcpuih8n7fth.png" alt="Best Use of GitHub Actions and Copilot: the court clerk" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain words:&lt;/strong&gt; every time I push code, a robot clerk re-checks that the court still rules the way it should.&lt;/p&gt;

&lt;p&gt;GitHub Actions runs these checks automatically on GitHub's computers, on every push. That's called CI, short for continuous integration.&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%2Fds6f2k0laitao9bruxqa.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%2Fds6f2k0laitao9bruxqa.png" alt="CI/CD: a push runs GitHub Actions checks, then deploys to GitHub Pages and Render" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every push runs:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;a syntax check of every file (&lt;code&gt;node --check&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;the full test suite on two versions of Node.js (20 and 22), covering the &lt;code&gt;decide()&lt;/code&gt; rules, the Gemma code (tested against a fake Ollama, so no real AI is needed), memory, timetables, TabPFN and the server&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;smoke test&lt;/strong&gt; of the real server: is it up, does it serve the app, does it fail politely when a key is missing, and does it block attempts to read files it shouldn't&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The run's summary page prints the whole rulebook as a table:&lt;/strong&gt; what &lt;code&gt;decide()&lt;/code&gt; rules for every combination of consequence and situation. You can read the court's logic on every single commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;main&lt;/code&gt; branch&lt;/strong&gt; (the live version of the code) is also published to &lt;strong&gt;GitHub Pages&lt;/strong&gt;, GitHub's free website hosting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For Copilot,&lt;/strong&gt; the file &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; tells GitHub's AI coding assistant the project's hard rules: rules pick verdicts, protect privacy and safety, never invent numbers. Anyone using Copilot on this repo gets those rules automatically. &lt;strong&gt;Dependabot&lt;/strong&gt; is a GitHub bot that keeps the tools these checks use up to date.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4bcnurv1538xwhs6ej5q.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%2F4bcnurv1538xwhs6ej5q.png" alt="GitHub Actions job summary showing the rules table" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Because the things you're avoiding are &lt;strong&gt;personal&lt;/strong&gt;. "Skip my doctor's appointment?" "Pay rent late?" "Go on a date with a stranger?" (Mom already said no.) That's not something I want sitting on someone else's server.&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%2Fnsccg2oi1a27vp6ha8dk.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%2Fnsccg2oi1a27vp6ha8dk.png" alt="What leaves your laptop: only labels and the one-line verdict" width="799" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Lazy (Gemma, on your laptop)&lt;/th&gt;
&lt;th&gt;A cloud chatbot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Your tasks, photos, timetable&lt;/td&gt;
&lt;td&gt;Never leave your laptop&lt;/td&gt;
&lt;td&gt;Sent to a company's server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What it remembers about you&lt;/td&gt;
&lt;td&gt;In your browser, editable, deletable&lt;/td&gt;
&lt;td&gt;Their memory, their rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost per question&lt;/td&gt;
&lt;td&gt;₹0&lt;/td&gt;
&lt;td&gt;Pay per use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can I make the rules stricter?&lt;/td&gt;
&lt;td&gt;Yes, it's one JS file&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An open model is what makes the "lazy" part possible. You can ask Lazy about every tiny thing, all day, for free, and nobody collects a diary of everything you're avoiding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest Limits (Lazy would want me to be upfront)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 4B is small.&lt;/strong&gt; It can misread messy photos and mix up timetable rows. That's why you can see and edit what it read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's slow on modest laptops.&lt;/strong&gt; On mine, a full run takes about &lt;strong&gt;1–2 minutes&lt;/strong&gt; (the fridge verdict took 83.7 seconds), and the first model load takes about &lt;strong&gt;40 seconds&lt;/strong&gt;. Reading a full week's timetable photo took about &lt;strong&gt;2 minutes&lt;/strong&gt;. The card always shows the real time. This is Slow and Steady, after all.&lt;/li&gt;
&lt;li&gt;The "hours saved" are Gemma's estimates, not measurements.&lt;/li&gt;
&lt;li&gt;The safety keywords are English-only and simple.&lt;/li&gt;
&lt;li&gt;No microphone yet (see above).&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 3 4B runs on your laptop through Ollama. It reads photos, asks the questions and fills in a strict JSON form, with code checks on every answer. It never picks the verdict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render.&lt;/strong&gt; The app's server is deployed on Render as a Blueprint-defined web service (&lt;code&gt;render.yaml&lt;/code&gt;): Singapore region, health checks, smart redeploys, secret keys kept in the dashboard, per-visitor rate limits, a 16 KB upload cap, and a footer showing the live version. Render is the only place the API keys live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs.&lt;/strong&gt; Judge Lazy's voice uses &lt;code&gt;eleven_v3&lt;/code&gt; audio tags chosen per verdict, generated gavel and snore sound effects, and spoken questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Sentry Agent Tracing.&lt;/strong&gt; One AI agent trace per run (&lt;code&gt;gen_ai.invoke_agent&lt;/code&gt; → &lt;code&gt;gen_ai.chat&lt;/code&gt; → &lt;code&gt;gen_ai.execute_tool&lt;/code&gt;) with token counts and timings, broken-JSON errors and disagreement feedback, and no private text sent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of TabPFN.&lt;/strong&gt; Predicts which verdict &lt;em&gt;you'd&lt;/em&gt; pick from six checked labels per past verdict, through the full upload, train and predict flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot.&lt;/strong&gt; GitHub Actions tests every push on Node 20 and 22, smoke-tests the server, prints the rulebook in the run summary and deploys to Pages. Copilot instructions and Dependabot keep contributors and tools in line.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Raga Vinjanampati: a broke student who now asks a potato for permission before doing anything. My mom thinks the potato is very sensible.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>My dad's scooter naps 9 hours a day. So I built a side hustle app to rent it out, and a local AI that settles "that scratch was already there."</title>
      <dc:creator>Raga Vinjanampati</dc:creator>
      <pubDate>Mon, 19 Oct 2026 06:01:47 +0000</pubDate>
      <link>https://dev.to/raga_vinjanampati/my-dads-scooter-naps-9-hours-a-day-so-i-built-a-side-hustle-app-to-rent-it-out-and-a-local-ai-2899</link>
      <guid>https://dev.to/raga_vinjanampati/my-dads-scooter-naps-9-hours-a-day-so-i-built-a-side-hustle-app-to-rent-it-out-and-a-local-ai-2899</guid>
      <description>&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%2Fwcievde0j1hk4x9w5ut9.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%2Fwcievde0j1hk4x9w5ut9.png" alt="The Idea" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Your scooter sits idle 9 hours a day. IdleWheels lets a neighbour rent those hours, and an open-source AI running on &lt;em&gt;your own laptop&lt;/em&gt; settles the one argument that kills every rental: &lt;em&gt;"that scratch was already there."&lt;/em&gt; &lt;a href="https://idlewheels.onrender.com/#home" rel="noopener noreferrer"&gt;Try it live&lt;/a&gt; · &lt;a href="https://youtu.be/dUHp-ObJfpg" rel="noopener noreferrer"&gt;Watch the 60-second demo&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My dad looked at the parking lot outside his office and said something that wouldn't leave my head:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Every one of these vehicles is just sitting here until 6 PM. Somebody should be making money off that."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He's right. Every morning, millions of students and office workers in India park a scooter, bike or car at 9 and don't touch it until evening.&lt;/p&gt;

&lt;p&gt;That's &lt;strong&gt;9 hours a day&lt;/strong&gt; of a vehicle doing absolutely nothing. Meanwhile, someone three streets away needs wheels for exactly those hours: to get to college, to a job interview, to the hospital.&lt;/p&gt;

&lt;p&gt;So I tried to build the obvious side hustle: &lt;strong&gt;rent out the hours your vehicle is asleep.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And within five minutes I hit the real problem. It isn't booking. It's this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Owner:&lt;/strong&gt; "There's a new scratch on the side."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Renter:&lt;/strong&gt; "That was already there."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every rental ends with that argument. Nobody can prove anything, so nobody trusts anybody, so nobody rents.&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%2F9vd1siwhscwmir771u8p.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%2F9vd1siwhscwmir771u8p.png" alt="The argument" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I did what any reasonable engineering student would do. &lt;strong&gt;I handed the argument to an AI.&lt;/strong&gt;&lt;/p&gt;

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

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

&lt;p&gt;&lt;strong&gt;IdleWheels&lt;/strong&gt; lets neighbours rent each other's idle scooters, bikes and cars, by the hour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 Try it live: &lt;a href="https://idlewheels.onrender.com/#home" rel="noopener noreferrer"&gt;idlewheels.onrender.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It works in three steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. List your idle hours.&lt;/strong&gt; Add your vehicle, your area and the hours it's free (say 9:30 to 5:30). Not sure what to charge? Tap &lt;strong&gt;✨ Ask Gemma&lt;/strong&gt; and it suggests a fair hourly price.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Book and chat.&lt;/strong&gt; A renter picks a day and a time window and sends a request. The app shows the cost upfront (7 hours × ₹35 = ₹245). Phone numbers stay hidden until the owner accepts. Then a chat opens inside the booking to sort out pickup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The handover check (the part I'm proudest of).&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At &lt;strong&gt;pickup&lt;/strong&gt;, 4 photos: front, left, right, rear.&lt;/li&gt;
&lt;li&gt;At &lt;strong&gt;return&lt;/strong&gt;, the same 4 again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3&lt;/strong&gt;, an open-weight AI model running on the &lt;em&gt;owner's own laptop&lt;/em&gt;, compares each pair and lists &lt;strong&gt;only the damage that's new&lt;/strong&gt;, with how serious it is and how confident it is.&lt;/li&gt;
&lt;li&gt;The verdict drops into the booking chat, and both people can save the full report as a PDF.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the whole dispute process. No arguing. Just two photos and a second pair of eyes that doesn't take sides.&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%2Fcmkviwp1d818w2lmf2e1.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%2Fcmkviwp1d818w2lmf2e1.png" alt="The real App" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who would pay for this?&lt;/strong&gt; Any owner who wants their idle vehicle to earn. And honestly, every small two-wheeler rental shop in India, which has the "that scratch was already there" argument every single day.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Part Where the AI Embarrassed Me
&lt;/h2&gt;

&lt;p&gt;My first version of the pricing feature was simple: show Gemma the vehicle, ask for a price per hour.&lt;/p&gt;

&lt;p&gt;For three similar scooters, it said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;₹95.&lt;/strong&gt; &lt;strong&gt;₹180.&lt;/strong&gt; &lt;strong&gt;₹600.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Six hundred rupees an hour. For a scooter. At that price it should come with a driver and a cup of chai.&lt;/p&gt;

&lt;p&gt;Small AI models are bad at maths and even worse at being consistent. So I split the job in two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma does what it's good at:&lt;/strong&gt; looking at the vehicle and sorting it into &lt;em&gt;budget&lt;/em&gt;, &lt;em&gt;standard&lt;/em&gt; or &lt;em&gt;premium&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A rate table does the maths.&lt;/strong&gt; I checked real Hyderabad self-drive rental rates this month (Royal Brothers, Zoomcar, Revv and others) and set IdleWheels a little &lt;em&gt;below&lt;/em&gt; them. A neighbour's scooter doesn't come with a company, an insurance package or roadside help, so it shouldn't cost the same.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmh7e3680rddhe8gi9zbp.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%2Fmh7e3680rddhe8gi9zbp.png" alt="AI Pricing" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That was the best lesson of the week:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Let the AI judge. Don't let it do arithmetic.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Here's what you can try in two minutes on the &lt;a href="https://idlewheels.onrender.com/#home" rel="noopener noreferrer"&gt;live app&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Browse idle vehicles&lt;/strong&gt; on the home page, pick a day and time, and send a request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List your own vehicle&lt;/strong&gt; and tap &lt;strong&gt;✨ Ask Gemma&lt;/strong&gt; for a price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open a booking&lt;/strong&gt; to see the chat. Phone numbers only appear once the owner accepts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run a handover check&lt;/strong&gt;: 4 pickup photos, 4 return photos, and the verdict lands in the chat.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Listings, bookings and chat work for anyone, straight away. The two AI features run on &lt;em&gt;your&lt;/em&gt; machine, so they need &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; with &lt;code&gt;gemma3:4b&lt;/code&gt; (the &lt;strong&gt;AI setup&lt;/strong&gt; tab walks you through it).&lt;/p&gt;

&lt;p&gt;There's also a static copy on GitHub Pages: &lt;a href="https://raga-v.github.io/idlewheels/" rel="noopener noreferrer"&gt;raga-v.github.io/idlewheels&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/Raga-V" rel="noopener noreferrer"&gt;
        Raga-V
      &lt;/a&gt; / &lt;a href="https://github.com/Raga-V/idlewheels" rel="noopener noreferrer"&gt;
        idlewheels
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Rent out your idle bike or car. A local Gemma checks every handover for new damage.
    &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;IdleWheels&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Your scooter naps 9 hours a day. Let it earn.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;College students and office-goers in India park their scooters, bikes and cars at 9 and don't touch them until 6. IdleWheels lets neighbours rent each other's vehicles for exactly those idle hours. Booking is the easy part. The hard part of peer-to-peer rental is trust, so the core of IdleWheels is an &lt;strong&gt;AI handover check&lt;/strong&gt; that runs on an open model on the owner's own laptop.&lt;/p&gt;
&lt;p&gt;Live: &lt;a href="https://idlewheels.onrender.com" rel="nofollow noopener noreferrer"&gt;https://idlewheels.onrender.com&lt;/a&gt; (also &lt;a href="https://raga-v.github.io/idlewheels/" rel="nofollow noopener noreferrer"&gt;https://raga-v.github.io/idlewheels/&lt;/a&gt;)&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;List the idle hours.&lt;/strong&gt; The owner says when the vehicle is free. Gemma sorts the vehicle into a price class (a Splendor is budget, a Royal Enfield is premium) and the app suggests a fair hourly price from real Hyderabad rental rates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request and chat.&lt;/strong&gt; A neighbour picks a day and hours and sees the total cost. The owner accepts or declines. Once accepted, both…&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/Raga-V/idlewheels" 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;Plain HTML, CSS and JavaScript, with no build step. A tiny Node.js server (one dependency: &lt;code&gt;pg&lt;/code&gt;) stores listings, bookings and chat in &lt;strong&gt;Render Postgres&lt;/strong&gt;. The AI never runs on the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📱 Browser ──4+4 photos──▶ 💻 Owner's laptop
                            (Ollama + Gemma 3 4B)
📱 Browser ◀──JSON verdict── 💻
📱 Browser ──text only────▶ ☁️ Render
                            (Node + Postgres:
                             listings, bookings, chat)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Getting a small model to compare two photos honestly&lt;/strong&gt; was the real work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Describe first, judge later.&lt;/strong&gt; Each request sends the pickup and return photo together, with a JSON schema that makes Gemma describe photo 1, then photo 2, and only &lt;em&gt;then&lt;/em&gt; list what changed. Ollama fills the fields in order, so the verdict rests on what the model just looked at, not a guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tell it what to ignore.&lt;/strong&gt; Two photos taken hours apart never match. The light changes, shadows move, reflections shift. The prompt tells Gemma to ignore all of that, plus dust.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Let it say "I don't know."&lt;/strong&gt; Gemma can answer &lt;code&gt;unsure&lt;/code&gt;, and it flags when the two photos don't show the same view. A dispute tool that invents damage is worse than no tool at all.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Deploying:&lt;/strong&gt; Render runs the server and Postgres from a &lt;code&gt;render.yaml&lt;/code&gt; blueprint. GitHub Actions checks the code, runs a server test, and publishes the static copy to GitHub Pages on every push.&lt;/p&gt;

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

&lt;p&gt;Because handover photos are &lt;strong&gt;private&lt;/strong&gt;. They show a number plate, often the owner's home, sometimes a face.&lt;/p&gt;

&lt;p&gt;In IdleWheels, those photos go from the browser to the owner's own laptop, and &lt;strong&gt;nowhere else&lt;/strong&gt;. The server only ever sees the text verdict: "new scratch, left side panel, minor."&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%2F7mzthlw1znn7ahikp725.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%2F7mzthlw1znn7ahikp725.png" alt="Guaranteed Privacy" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;IdleWheels (Gemma, local)&lt;/th&gt;
&lt;th&gt;A paid cloud vision API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Where the photos go&lt;/td&gt;
&lt;td&gt;The owner's own laptop&lt;/td&gt;
&lt;td&gt;Someone else's server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost per handover check&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;₹0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Paid per image, 8 images every time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A rental shop doing 50 handovers a day&lt;/td&gt;
&lt;td&gt;Still ₹0&lt;/td&gt;
&lt;td&gt;The bill grows every day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Want sharper eyes?&lt;/td&gt;
&lt;td&gt;Swap to &lt;code&gt;gemma3:12b&lt;/code&gt;, or fine-tune on scratch photos&lt;/td&gt;
&lt;td&gt;Wait for the vendor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A side hustle runs on thin margins. A rental that earns ₹245 can't pay for an API call on every handover. An open model running on a laptop the owner already has makes the trust layer &lt;strong&gt;free&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest Limits (because judges can smell hype)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A 4B model on a laptop can miss hairline scratches and get fooled by glare. It's a second pair of eyes, not a judge.&lt;/li&gt;
&lt;li&gt;Identity is just a name, a phone number and a key saved in your browser. A real launch needs OTP verification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The legal bit:&lt;/strong&gt; in India, renting out a privately registered (white-plate) vehicle for money needs commercial registration and insurance. IdleWheels is a demo of the trust layer. The fastest real-world path is licensed rental shops, who have the exact same scratch argument every day.&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 3 4B (vision) is the core of the app. Running locally through Ollama, it compares pickup and return photos for every angle and returns the new damage, severity and a verdict as structured JSON. It also looks at the vehicle and picks its price class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt;: Render hosts the whole app: the Node.js server and front end as a web service, and Render Postgres for listings, bookings and chat, all defined in &lt;code&gt;render.yaml&lt;/code&gt;. Live at &lt;a href="https://idlewheels.onrender.com/#home" rel="noopener noreferrer"&gt;idlewheels.onrender.com&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot&lt;/strong&gt;: GitHub Actions automates the project. Every push checks the code, runs a server test and deploys a static copy to &lt;a href="https://raga-v.github.io/idlewheels/" rel="noopener noreferrer"&gt;GitHub Pages&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;My dad came up with the idea. I built it in one very caffeinated morning. He has already asked about his commission.&lt;/p&gt;

&lt;p&gt;If your vehicle is napping right now, &lt;a href="https://idlewheels.onrender.com/#home" rel="noopener noreferrer"&gt;go list it&lt;/a&gt;. And if you've ever lost a "that scratch was already there" argument, tell me about it in the comments. 👇&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— Raga Vinjanampati, a broke student whose scooter earns more than she does (on paper)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>I built an app that lets 2.5-billion-year-old rocks guilt-trip you. My college rocks are very disappointed in me.</title>
      <dc:creator>Raga Vinjanampati</dc:creator>
      <pubDate>Mon, 12 Oct 2026 06:23:34 +0000</pubDate>
      <link>https://dev.to/raga_vinjanampati/i-built-an-app-that-lets-25-billion-year-old-rocks-guilt-trip-you-my-college-rocks-are-very-20eb</link>
      <guid>https://dev.to/raga_vinjanampati/i-built-an-app-that-lets-25-billion-year-old-rocks-guilt-trip-you-my-college-rocks-are-very-20eb</guid>
      <description>&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%2Fwnan2zjbdjuoytwn11nn.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%2Fwnan2zjbdjuoytwn11nn.png" alt="Turns out even rocks have more personality then me." width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&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;p&gt;A rock told me my face was a distraction.&lt;/p&gt;

&lt;p&gt;Not a person. A rock. A big granite boulder in Hyderabad, about 2.5 billion years old.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Do try not to stare so intensely. Your face is a distraction."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To be fair, I did build the app that made it say that. So that one's on me.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Adopt-a-Rock&lt;/strong&gt; is a Tamagotchi, but it's a rock. And it only works if you go outside.&lt;/p&gt;

&lt;p&gt;Hyderabad is full of huge, ancient rocks. My college, Gokaraju Rangaraju (GRIET), has them too. I've walked past them for years and never once asked how they were doing.&lt;/p&gt;

&lt;p&gt;So now they tell you. Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Find a rock. Take one photo.&lt;/strong&gt; The app saves where the rock is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait.&lt;/strong&gt; The rock is asleep. It's 2.5 billion years old. It doesn't reply the same day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It wakes up.&lt;/strong&gt; Overnight, a free AI running on my laptop looks at the photo and gives the rock a name, a personality, and a grudge. It even gets its own voice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go back.&lt;/strong&gt; When you visit the rock again, it talks to you through your earbuds. Each visit unlocks a new bit of its story.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay away, and it texts you.&lt;/strong&gt; Rocks get lonely. And dramatic.&lt;/li&gt;
&lt;/ol&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%2F77fwfecss3npgs8ix2dq.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%2F77fwfecss3npgs8ix2dq.png" alt="Here's the app!" width="800" height="408"&gt;&lt;/a&gt;&lt;br&gt;
You can't look after a rock from your bed. You have to go outside.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

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

&lt;p&gt;Every rock line in the video comes straight from the app. I didn't write a single one of their insults. They came up with those on their own. (The googly eyes were my idea. The rocks did not consent.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet the Rocks
&lt;/h2&gt;

&lt;p&gt;I tested the app on photos of famous Hyderabad rocks. Here's who woke up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🪨 Khajanchi&lt;/strong&gt; &lt;em&gt;(patiently grumpy)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wants to be dusted with "a single, perfectly formed sand grain each morning."&lt;/li&gt;
&lt;li&gt;Has a neighbour rock called Prakasan, who is "always trying to get people to mistake him for me."&lt;/li&gt;
&lt;li&gt;On how I photographed it: "It's a poor angle. A very poor angle."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🪨 Katta&lt;/strong&gt; &lt;em&gt;(grumbling, stoic)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I consider all shadows an intrusion."&lt;/li&gt;
&lt;li&gt;Hates construction work nearby: "It's a crime against geological stability."&lt;/li&gt;
&lt;li&gt;Secretly likes the light through the leaves. Even rocks have a soft side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🪨 Chilakalu&lt;/strong&gt; &lt;em&gt;(cantankerous)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thinks the pebbles around it are arranged wrong. It's been annoyed about this for a long time.&lt;/li&gt;
&lt;li&gt;When I took its photo: "Focus on the boulders, woman."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🪨 Gael&lt;/strong&gt; &lt;em&gt;(irritated)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I've developed a distinct dislike for the colour orange."&lt;/li&gt;
&lt;li&gt;The one that told me my face was a distraction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🪨 My college rocks&lt;/strong&gt; &lt;em&gt;(asleep 💤)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then I went to adopt the rocks at my own college, GRIET.&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%2Fo8ry0skgyp6ry57vtej0.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%2Fo8ry0skgyp6ry57vtej0.png" alt="Me sitting next to my adopted rock on campus" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Me and my rock. Only one of us is 2.5 billion years old. Only one of us has a braid.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7yxy7nf2pvxg97hkq8ux.jpeg" 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%2F7yxy7nf2pvxg97hkq8ux.jpeg" alt="The rocks at my college" width="800" height="602"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;This one lives at my college. It has seen more batches graduate than any professor.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;These two are wedged between the college buildings. The buildings came later. The rocks have opinions about that.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;They haven't said a word yet. They're still asleep, waiting for the laptop to wake them up. They've waited 2.5 billion years for someone to notice them, so they're in no hurry. But I can already tell they're disappointed in me. I've walked past them for years and never said hi.&lt;/p&gt;
&lt;h2&gt;
  
  
  Skip a Visit, Get a Text
&lt;/h2&gt;

&lt;p&gt;If you don't visit, your rock starts messaging you. These are real messages from Khajanchi:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;3 days:&lt;/strong&gt; "A pigeon has built a nest in one of my larger cracks. Really?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7 days:&lt;/strong&gt; "The ORR traffic continues its incessant, grating roar."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;14 days:&lt;/strong&gt; "A particularly aggressive auto-rickshaw nearly clipped my base. The audacity!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My mom doesn't guilt-trip me this well.&lt;/p&gt;
&lt;h2&gt;
  
  
  No Proxy Attendance
&lt;/h2&gt;

&lt;p&gt;Every college student knows the trick: get a friend to mark you present. This app doesn't fall for it.&lt;/p&gt;

&lt;p&gt;A visit only counts if you're actually standing near the rock &lt;strong&gt;and&lt;/strong&gt; the photo matches. Try to check in with a different rock, and the real one gets offended:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Prakasan is a fool. He's shaped differently, he's covered in algae, and he constantly tries to block my sunlight. He is not me." — Khajanchi&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Stricter than my college's attendance system.&lt;/p&gt;
&lt;h2&gt;
  
  
  Bloopers
&lt;/h2&gt;

&lt;p&gt;The AI is small, so it gets things wrong. My favourites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I asked Gael for &lt;strong&gt;one&lt;/strong&gt; "3 days without a visit" message. It kept going: &lt;em&gt;"Nine days. A pigeon sat on me. I let it."&lt;/em&gt; Its 14-day message went all the way to &lt;em&gt;"Thirty-five days. I am parched, utterly depleted."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Katta finished a story, then kept typing closing quote marks: &lt;code&gt;” ” ” ” ” ” ” ”&lt;/code&gt;. Forever.&lt;/li&gt;
&lt;li&gt;Khajanchi wrote a scene where I put a plastic bottle next to it for the photo. &lt;strong&gt;There was no bottle.&lt;/strong&gt; The AI just decided I was that kind of person.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The tricky part: phones can't run a big AI model easily, and there's no signal near most rocks. So I split the work in two.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rocks are slow.&lt;/strong&gt; Everything that happens &lt;em&gt;at the rock&lt;/em&gt; runs on the phone, with no internet. The heavy AI work happens at home on my laptop, while the rock "sleeps".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PHONE (works offline)                 LAPTOP (at home)
─────────────────────                 ────────────────
Camera + GPS                          Gemma 3 (the rock's brain)
Photo matching (CLIP)        ⇄        Piper (the rock's voice)
Saved stories + voices      Wi-Fi     Writes new stories overnight
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 4B&lt;/strong&gt; (Google's open model) runs on my laptop through &lt;strong&gt;Ollama&lt;/strong&gt;. It looks at the rock's photo and writes the personality, stories, and nagging texts. Waking up one rock takes about 2 minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLIP&lt;/strong&gt; runs right inside the phone's browser. It checks whether your photo shows the same rock. It works with Wi-Fi and mobile data turned off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Piper&lt;/strong&gt; turns the text into speech. Each rock gets its own voice and talks a little slowly, because rocks are never in a hurry.&lt;/li&gt;
&lt;li&gt;When the phone gets back on home Wi-Fi, it syncs with the laptop and picks up any new stories.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Three things I learned about getting a small AI to be funny:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It copies examples.&lt;/strong&gt; If I put one example line in my instructions, every rock repeated it. So I describe the style instead of giving examples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make it look first.&lt;/strong&gt; I ask the AI to list what it sees in the photo before it writes anything. That way the stories mention real details, like cracks, trees and the building behind the rock.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check its work.&lt;/strong&gt; The code throws out broken answers (like the quote-mark spiral) and asks again, up to 3 times.&lt;/li&gt;
&lt;/ol&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/Raga-V" rel="noopener noreferrer"&gt;
        Raga-V
      &lt;/a&gt; / &lt;a href="https://github.com/Raga-V/deccan-rocks" rel="noopener noreferrer"&gt;
        deccan-rocks
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Adopt a 2.5-billion-year-old granite boulder in Hyderabad. It talks, slowly and with grudges. Offline phone PWA + local Gemma, no cloud.
    &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;Deccan Rocks&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Adopt a 2.5-billion-year-old granite boulder in Hyderabad. Visit it. It talks to you, slowly and with grudges.&lt;/p&gt;

&lt;p&gt;Everything runs on your own devices. The phone works fully offline on the hill. The rock's brain (Gemma) runs on a
laptop at home. No cloud API is involved, and GPS and photos never leave your phone and laptop.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The design trick: rocks are slow&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;In the field (phone, offline)&lt;/th&gt;
&lt;th&gt;At home (laptop, local)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Snap the rock, read GPS&lt;/td&gt;
&lt;td&gt;FastAPI + SQLite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLIP ViT-B/32 in the browser (transformers.js) checks it's the same rock&lt;/td&gt;
&lt;td&gt;Gemma 3 via Ollama looks at the photo and invents a personality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPS check: within ~40 m of the adoption spot&lt;/td&gt;
&lt;td&gt;Gemma writes the next 3 chapters, a rejection line and guilt-trip nags&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plays the next chapter's voice line, cached on the phone&lt;/td&gt;
&lt;td&gt;Piper TTS gives every rock its own voice&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;A rock you adopt is &lt;strong&gt;asleep 💤&lt;/strong&gt;…&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/Raga-V/deccan-rocks" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;Because a rock on a hill doesn't have Wi-Fi. Neither does most of my college.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Adopt-a-Rock (open, runs on my devices)&lt;/th&gt;
&lt;th&gt;A paid cloud AI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Works with no signal&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where your location goes&lt;/td&gt;
&lt;td&gt;Your phone and laptop only&lt;/td&gt;
&lt;td&gt;Someone else's server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost per visit&lt;/td&gt;
&lt;td&gt;₹0&lt;/td&gt;
&lt;td&gt;Pay every time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can I change how the rock thinks?&lt;/td&gt;
&lt;td&gt;Yes. Edit it, swap models, retrain it&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An app like this knows where you go every day. For a student, that's basically your whole routine: which classes you skip and how long you spend at the canteen. I didn't want that on anyone else's server. With open models, it doesn't have to be.&lt;/p&gt;

&lt;p&gt;Also, since every visit is free, your rock can talk to you every day for four years of college. For a rock, four years is about one blink.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Serious Bit
&lt;/h2&gt;

&lt;p&gt;The rocks have good reason to be grumpy. Hyderabad's ancient rock formations have been disappearing to construction for decades, and people here have fought for years to save them.&lt;/p&gt;

&lt;p&gt;I gave the AI a list of things a Hyderabad rock might complain about: peacocks, biryani smell, rain puddles, auto-rickshaws, construction. Almost every rock picked construction or traffic. They know.&lt;/p&gt;

&lt;p&gt;I started this as a silly project. Now I notice every rock on my way to class.&lt;/p&gt;

&lt;p&gt;Go adopt a rock. It's been waiting since before your college was built. It will complain about that too.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— Raga Gowtami, student at GRIET, now legally responsible for several very disappointed rocks&lt;/em&gt; 🪨&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. If you build your own and your rock insults you, drop its best line in the comments. Mine called my face a distraction. Beat that.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
