This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Every day I have the same argument with myself.
Me: Do I really need to go to the 8 AM lecture?
Also me: You're going to regret this.
Me: I'll regret it later. Later is a problem for future me.
So I hired a professional. He's a potato. He lives on a couch. He wears sunglasses indoors. His name is Lazy.
To test him, I asked Lazy and my mom the same questions about my own chores. Lazy told me to skip a date and clean the fridge. My mom said exactly the same thing. I have never felt so outnumbered.
In 30 seconds:
What it is: 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. #
The trick: an open AI model (Gemma 3) runson your laptop 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. #
The proof: my mom and Lazy answered the same questions. I agreed with Lazy 7 times out of 10. #
The stack: Gemma 3 + Ollama, Render, ElevenLabs, Sentry, TabPFN, GitHub Actions + Copilot. Each one has exactly one job.
#
What I Built
Do I Need to Do This? is a web app for people who are tired of deciding. You type the task you're avoiding. Lazy asks you up to three quick questions, and you answer with a tap. Then he gives you one honest verdict:
The twist: Lazy is not allowed to let you off the hook for the important stuff. Health, money, official paperwork and anything graded can never get "Skip it". Lazy is lazy, not irresponsible.
And the part I'm proudest of: the AI doesn't pick the verdict. 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.
Meet Lazy (a short, cute video)
#
Demo
Try it: raga-v.github.io/do-i-need-to-do-this
The AI runs on your laptop, so you'll need Ollama, a free app for running AI models locally, with the gemma3:4b model downloaded. The app's AI setup screen gives you the exact one-line command to copy.
What you can do:
Ask about one task. "Go to the 8 AM lecture tomorrow", "Pay the electricity bill", "Reply to the group chat", "Iron my shirt". 2. Add a photo. A timetable, a notice, a screenshot. Lazy reads it before he asks anything. 3. Plan my lazy day. Save your timetable once, and Lazy sorts your whole day intoMust do · Lazy minimum · Skip · Later . 4. Hear the verdict. Lazy delivers it like a tired judge:"[sighs] Skip it. … Court is adjourned."
#
The Lazy Payoff: Mom vs. Lazy
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.
Straight from the app's History screen:
- 13 tasks judged.
I agreed with Lazy 7 out of 10 times (I answered "Would you have decided the same?" on 10 of them). #
5.1 hours back this week. That's the sum of Gemma's own effort estimates for everything Lazy said to skip or shrink, not a stopwatch.
Highlights from the tape:
"Do you think I should reply in the family group chat?" Mom:"Why didn't you reply yet?" Lazy, slightly more relaxed:Do the lazy minimum. Just send a quick "okay" message. About 2 minutes. #
"Do you think I should go on a date with a guy I never met before?" Mom:"No. Never. And ever." Lazy asked one question,"Would letting him down be bad?" , and then:Skip it."Since you've never met him, a simple decline won't cause any issues." Mom and the potato, united. #
"Do you think I should clean the fridge before Diwali?" Mom:"Do you think the sky is blue? Obviously you have to." Lazy jumped off the couch:Yes, do it."Your mum will probably get annoyed if you don't clean the fridge." He knows her. Judged by Gemma in 83.7 seconds, on my laptop. #
Where I disagreed: "Do you think I should do my little sister's assignment?" I would have skipped it. Lazy saidDo the lazy minimum. 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.
#
Code
Type the task you're avoiding ("Go to the 8 AM lecture tomorrow", "Pay the electricity bill"). Optionally add a line of context or a photo of a timetable, notice or screenshot. Gemma 3 runs on your own laptop, asks up to three tap-to-answer questions, and then the app gives one honest verdict: | Verdict | | 🛋️ | Skip it | | 🪫 | Do the lazy minimum (and what it is) | | 📅 | Do it later (by when) | | 🚨 | Yes, do it | | 🤔 | Not sure yet |
Meet Lazy 🥔🛋️ #
Lazy is a couch potato in sunglasses (an inline SVG in public/mascot.js, no image files). Lazy chills on the couch on the home screen, thinks hard (with a rotating status line: "Lazy is consulting the couch…", "Weighing your excuses…") while Gemma works, and pops in with a mood that matches the ruling: asleep for Skip it…
#
How I Built It
A 20-second jargon decoder
You don't need to be an engineer to follow the rest of this post. These are the only terms that matter:
| Term | What it means here |
| Gemma 3 4B | An open AI model from Google. "4B" means 4 billion parameters: small enough to run on a normal laptop. |
| Ollama | A free app that runs AI models on your own computer, like a media player for models. |
| JSON | A simple, strict text format for data, made of "name": value pairs that code can read reliably. |
| Schema | The fixed list of fields the JSON must have. Anything else gets rejected. |
| decide() | The JavaScript function, in the file public/decide.js , that picks every verdict. No AI inside. |
| Token | A chunk of text, roughly ¾ of a word. Models read and write in tokens, so token counts measure how much work the AI did. |
| API key | A password that lets an app use a paid online service (like ElevenLabs' voices). |
The one rule: the AI asks, the code decides
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 reading and asking, and terrible at being consistent. 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.
So I split the job in two. Here's where everything runs:
How to read this diagram: everything in the purple box happens on your laptop, and that includes the AI. The white box is a small server on Render whose only job is holding the API keys. The orange box is the online services. The arrows show the only things that ever reach them: one line of text to speak, and a few labels.
And here's one run, from your question to Lazy's gavel:
Read it top to bottom. Each numbered arrow is one message passing between you, Gemma, the rules and the online services. In words:
Gemma reads. If you add a photo (say, your timetable), Gemma copies downonly what it can actually see . Anything unreadable is marked[?] instead of guessed, and you can correct what it read.
2.
Gemma asks. Up to 3 questions, each with 2–4 answers you tap, and only about what it doesn't already know.
3.
Gemma writes down facts, not opinions. Instead of chatting, it has to fill in a form, as JSON. Ollama'sformat 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:
(An example of the shape, not a real log. The comments are mine, for this post.)
- Plain JavaScript decides. The
decide()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.
The rulebook in three steps: (1) if Gemma is less than 50% sure, Lazy says "Not sure yet". (2) Otherwise, how bad skipping would be picks the verdict. For example, "minor" and only affects you gives Skip it. (3) 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.
Gemma tried to cheat. The code caught it.
A small model running on a laptop makes mistakes. Instead of hoping a better prompt would fix them, I added guard rails in code: 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:
It filed "Pay the electricity bill" under "other". Now, if the task's own words mention a bill, payment, doctor, exam or passport, it's treated as protected, whatever category Gemma picked. #
It "quoted" things I never said. 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*"They'll cut off the power."* Nobody said that. #
It told someone to skip the laundry because their attendance was high. 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. #
Its maths was creative. 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. #
If Gemma is less than 50% sure, Lazy says "Not sure yet". He'd rather ask than guess.
Every time the code overrules Gemma, the verdict card says so: "The app overruled Gemma." No secret edits.
Lazy remembers you (without spying on you)
Memory. After each verdict, Gemma suggests up to 3lasting 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. #
Timetable. 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**"check this"** badge instead of a guess. #
Plan my lazy day. Gemma fills in one form for every class or task on today's timetable, in a single request, and then thesamedecide() rules judge each one.
All of this is saved in your own browser's storage (localStorage) and only ever sent to Gemma, on your own laptop.
Small things that make it feel alive
Lazy is drawn entirely in code. 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. #
Funny sounds, generated live in the browser with the Web Audio API (the browser's built-in synthesizer), so there are no audio files either: asnore for skip, a coffeeslurp for the lazy minimum, atick-tock for later, a panickedboing for "do it", and aflump as Lazy lands on the couch. #
What I didn't ship: a microphone. 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.
#
How each partner technology is used
Every partner has exactly one job in Lazy's household. Each section starts with the plain-English version, then the details for the curious.
In plain words: 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.
Vision: reads timetable photos, notices and screenshots, copying down only what's visible. #
Conversation: decides which follow-up questions to ask, and writes the tap-to-answer options. #
Filling in the form: returns the JSON facts shown above. If the JSON comes back broken, the app retries once and tells Gemma exactly what was wrong. #
Memory, timetables and planning: each is its own small, separate request with its own form, and a cap on how much Gemma may write.
Gemma never picks the verdict, 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.
In plain words: 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.
That server is one file, server.js, with zero extra code libraries. Render runs it as a web service: a program that's always on and answers requests. Render calls a config file that sets everything up a Blueprint, and mine is render.yaml:
(Trimmed for the post. The full file is in the repo.)
One-click deploy: anyone can copy the repo and get the same server with one click. #
Secrets stay out of the code: every key lives only in Render's dashboard. #
Safe on the open internet: - Files are compressed before they're sent (gzip), so the app loads faster.
- Each visitor gets a limited number of requests (rate limiting), so nobody can drain my API credits.
- 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.
You always know what's live: the app's footer shows exactly which version is running. It reads Render'sRENDER_GIT_COMMIT setting, the ID of the code commit. Render also checks/healthz before it switches visitors to a new version.
In plain words: Lazy talks. He reads you his questions, bangs a gavel, and announces the verdict like a very tired judge.
A voice with a personality. When you tap "Hear the verdict", the app asks the server (at/api/speak ) to voice one line. It uses ElevenLabs' newest model,eleven_v3 , which understandsaudio tags : stage directions in square brackets that change how the line is performed. The server adds them per verdict:[sighs] Skip it. … [laughs] Court is adjourned. or[clears throat] Yes, do it. If v3 is unavailable, it falls back to the oldereleven_multilingual_v2 voice. #
Sound effects, generated by ElevenLabs: agavel bang before every verdict, and asnore 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. #
Lazy reads each question aloud, so it feels like a conversation, not a form. #
It can't be abused as a free voice service. 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.
In plain words: 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.
Two Sentry words first. A trace is the full recording of one run. A span is one step inside it, drawn as a bar on a timeline. Each run is one trace that reads like a story: agent, then Gemma, then Gemma again, then the rules.
I use Sentry's AI agent span types, so Sentry knows what each step is: -
gen_ai.invoke_agent is the whole run. #
gen_ai.chat is one call to Gemma. There's one per step: reading the photo, asking questions, filling in the facts. #
gen_ai.execute_tool is the rules deciding. I named itdecide_verdict . #
Each Gemma step records 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. #
The rules step records the facts that went in and the verdict and rule that came out. A surprising verdict can be traced to the exact rule. #
Broken JSON from Gemma is logged as an error, labelled with the step and attempt. #
When you disagree with the court, Sentry records both verdicts and the rule that fired. That's the best signal for tuning the rules. #
Privacy: no prompts, replies, photos or task text are ever sent to Sentry. Only lengths and labels.
In plain words: the rules give the official verdict. TabPFN guesses what you 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.
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.
What it learns from: each time you answer "Would you have decided the same?", that verdict becomes one row. Once you haveat least 10 rows (with at least two different answers), the app sends TabPFNsix labels per row , plus what you actually chose: 1. category 2. consequence 3. days until the deadline 4. whether it affects others 5. whether it can be fixed later 6. effort in minutes
No words, ever.
The server checks every value against fixed lists and number ranges, and rejects anything else (including free text) before it reaches TabPFN. #
The full TabPFN flow: upload your history, train on it, then ask for the odds of each verdict. The card shows*"Based on your past choices, you'd probably pick: X (NN%)"* , with a bar for each verdict. #
A "Teach Lazy" progress bar in History shows how close you are to 10. #
Honest limit: with this little data, it's a hint about your habits, not a crystal ball. The rules' verdict always wins.
In plain words: every time I push code, a robot clerk re-checks that the court still rules the way it should.
GitHub Actions runs these checks automatically on GitHub's computers, on every push. That's called CI, short for continuous integration.
Every push runs: - a syntax check of every file (node --check )
- the full test suite on two versions of Node.js (20 and 22), covering the
decide()rules, the Gemma code (tested against a fake Ollama, so no real AI is needed), memory, timetables, TabPFN and the server - a smoke test 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
The run's summary page prints the whole rulebook as a table: whatdecide() rules for every combination of consequence and situation. You can read the court's logic on every single commit. #
The main branch (the live version of the code) is also published toGitHub Pages , GitHub's free website hosting. #
For Copilot, the file.github/copilot-instructions.md 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.Dependabot is a GitHub bot that keeps the tools these checks use up to date.
#
Why Does Open Innovation Matter?
Because the things you're avoiding are personal. "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.
| | Lazy (Gemma, on your laptop) | A cloud chatbot | | Your tasks, photos, timetable | Never leave your laptop | Sent to a company's server | | What it remembers about you | In your browser, editable, deletable | Their memory, their rules | | Cost per question | ₹0 | Pay per use | | Can I make the rules stricter? | Yes, it's one JS file | No |
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.
#
Honest Limits (Lazy would want me to be upfront)
Gemma 3 4B is small. It can misread messy photos and mix up timetable rows. That's why you can see and edit what it read. #
It's slow on modest laptops. On mine, a full run takes about1–2 minutes (the fridge verdict took 83.7 seconds), and the first model load takes about40 seconds . Reading a full week's timetable photo took about2 minutes . The card always shows the real time. This is Slow and Steady, after all.
-
The "hours saved" are Gemma's estimates, not measurements.
-
The safety keywords are English-only and simple.
-
No microphone yet (see above).
#
Prize Categories
Best Use of Gemma. 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. #
Best Use of Render. The app's server is deployed on Render as a Blueprint-defined web service (render.yaml ): 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. #
Best Use of ElevenLabs. Judge Lazy's voice useseleven_v3 audio tags chosen per verdict, generated gavel and snore sound effects, and spoken questions. #
Best Use of Sentry Agent Tracing. One AI agent trace per run (gen_ai.invoke_agent →gen_ai.chat →gen_ai.execute_tool ) with token counts and timings, broken-JSON errors and disagreement feedback, and no private text sent. #
Best Use of TabPFN. Predicts which verdictyou'd pick from six checked labels per past verdict, through the full upload, train and predict flow. #
Best Use of GitHub Copilot. 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.
Raga Vinjanampati: a broke student who now asks a potato for permission before doing anything. My mom thinks the potato is very sensible.