This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
Should I Bother? (The Lazy Bookie) turns weather chores into bets on doing nothing.
You type your chores in one sentence: "water the plants, hang the laundry, rinse the car". A Gemma 4 bookmaker running on my own laptop reads the forecast and gives you odds that the sky does the job for you:
- Water the balcony plants? Showers are possible overnight: toss-up, 50 %.
- Rinse the car? Barely any rain: unlikely, 35 %.
- Clean the windows? Gemma picks the best window to do it, so the rain doesn't undo your work.
You bet on doing nothing. The odds and the payout are locked in. At settle time, you answer with one tap or an after photo, and Gemma judges the result: "Still moist, all fine", and the receipt is stamped PAID OUT. The Score screen shows your rank (from Hyperactive squirrel up to Koala and beyond), what the sky saved you (minutes, litres of water, kWh), and how honest Gemma's odds really are next to a simple rule's.
Who gets to be lazier? Anyone with a balcony, a washing line, a car on the street or a terrace, in a city where the weather keeps changing. It doesn't tell you to skip a chore blindly: safety (heat, frost, storms) is never a bet, and a fixed backstop always overrides Gemma.
What's in it:
- Plants and laundry bets: water the balcony plants, line-dry today, laundry overnight, and a laundry planner for the best drying day.
- City rain bets: rinse the car, the bike or the terrace, and fill the rain barrel.
- Advice cards: clean the windows, sweep the leaves, paint outdoors, feed the lawn.
- Rescue: cash out when the forecast turns against your bet.
- Appeals, ranks, achievements, and an onboarding with a GPS button or a place search.
- "How Gemma decided" on every bet: the prompt version, the tool call, and the exact forecast hours Gemma saw.
Demo
41 seconds, recorded from the real app with sample data. Voice: Piper "Ryan" (RyanSpeech dataset, CC BY-NC-SA 4.0). Music: original.
Try it yourself in two minutes, with no GPU and no model, using sample data, a fake model and fake weather:
git clone https://github.com/adricasi/ShouldIBother.git
cd ShouldIBother
npm ci && npm run build && npm run sib -- demo
Open the link it prints. Every screen carries a "Sample data · fake model" label, so nothing pretends to be Gemma.
The real thing runs at home: Gemma 4 E4B in Ollama on the laptop, and the phone pairs over home Wi-Fi with a one-time link.
Code
Should I Bother?
The Lazy Bookie: a bookmaker that bets on doing nothing. Tell it a weather chore, and Gemma 4, running on your own laptop, reads the forecast and quotes odds that the sky will do it for you. Bet on the weather or do it yourself; every bet settles on evidence.
Try the demo → · How it works · Gemma · Run it yourself · Hosted mode · Contributing
Contents
- Why Should I Bother?
- Features
- Screenshots
- How it works
- Quick start
- Run it on your laptop, step by step
- Configuration
- Hosted mode
- Architecture
- Privacy and security
- Testing and quality
- Project structure
- Status and roadmap
- Hacktoberfest challenge
- Later commits
- Contributing
- Licences and acknowledgements
- Documentation
Why Should I Bother?
On the right day, the weather does some chores for you: the rain waters the balcony, the sun and wind dry the washing, a cool night stands in for the…
- Stack: TypeScript (strict) on Node 24: Fastify, React + Vite, zod, better-sqlite3, sharp.
-
Fine-tune pipeline: a Python
training/folder (uv, QLoRA). - Licence: MIT.
-
Docs to start with:
- README;
- how Gemma is integrated;
- architecture, with 13 diagrams;
- how it was built;
- the spec and the ADRs.
How I Built It
Gemma decides, code executes
Gemma 4 E4B runs locally in Ollama on 127.0.0.1. Every model call goes through one ModelClient interface with four runtimes:
| Runtime | Used for |
|---|---|
| Ollama | Gemma 4 E4B at home |
| llama.cpp | Gemma 4 audio, for voice capture (behind a flag) |
| DigitalOcean Serverless Inference | The optional hosted mode |
| Fake | Recorded, synthetic fixtures for tests and the demo |
Gemma does seven jobs, each with a versioned prompt file (prompts/<job>.v<n>.md), a zod schema, a retry budget and a deadline:
- Listener: splits your sentence into chores and chore types.
- Inspector: reads a before photo (soil, wilting, laundry) into observations.
-
Bookmaker: calls the
get_forecasttool and answers with an odds band (very likely, likely, toss-up, unlikely, very unlikely = 85/70/50/35/15 %), a short reason and a settle time. - Safety guard: checks for heat, frost and storms before a bet opens.
- Judge (and appeals): reads the after photo or your tap, plus the recorded weather, and returns the verdict.
- Laundry planner: picks the best drying day out of four.
- Advisor: picks the best window to clean the windows, sweep or paint, from a 72-hour forecast.
The important part is what code does around Gemma:
- Gemma never returns a raw percentage. It names a band, and code maps it to odds and computes points: win = (100 − odds) × evidence multiplier (photo ×1.0, tap ×0.5); losses are −25 / −50 / −150.
- A rule baseline is computed for every card and stored on every bet. If Gemma is two or more bands away from the rule, it must explain why or ask a question. If it skips the forecast tool, it gets one retry, and then the card shows labelled rule odds.
- Safety is never a bet. A fixed heat, frost and storm backstop overrides Gemma.
- Settlement is always a Gemma verdict. If Gemma is offline, the bet waits, and it auto-settles at ×0.5 only after 24 hours. Odds are locked at bet time, with undo only within 5 minutes.
- Everything typed or photographed is untrusted data, fenced off from the instructions in every prompt, and every answer is schema-validated before it touches the database.
-
Every decision is logged in
gemma_decisions: model, digest, prompt version, tool mode, retries, latency, and the forecast hoursget_forecastreturned. That log is what the "How Gemma decided" panel shows. - Calibration is measured, not assumed. The Score screen compares Gemma's bands with what really happened, next to the rule's figure. Bets priced by the rule never count toward Gemma's calibration.
Evaluation and fine-tune
-
Evaluations:
sib eval <job>runs an eval set per job (seven sets). - Backtest: replays past weather using only forecasts that were available at decision time, so there is no lookahead.
- Fine-tune (QLoRA): a full pipeline for the bookmaker. A dataset is built from a weather snapshot with a fixed synthetic habit profile; the build fails if anything from my real household config appears in it, and the September–October data is held out. The pipeline trains, merges, exports to GGUF with a Modelfile for Ollama, and compares base and fine-tuned models on the hold-out.
Spec-driven, with AI agents
I built it spec-first:
- Idea brief. An ideation session produced the brief and a Go verdict.
-
Spec in
docs/spec/. It covers product, requirements, design and tasks, with stable IDs: 32 requirements, 149 acceptance criteria in EARS style, 13 non-functional requirements, 42 tasks and 11 ADRs. Every later change went through the spec first: the city rain bets, the advice cards and the hosted mode were each a spec change before any code. - Implementation. Claude Code coordinated parallel worker agents, one task each. Tests were written from the acceptance criteria first, against a fake Gemma with recorded, synthetic fixtures, so CI never needs a GPU.
- Review. Every pull request was reviewed by specialised reviewer agents (code, game rules, security, UX and spec), then got one round of fixes.
- Result. 56 merged pull requests, around 2,600 automated tests plus browser end-to-end tests, and a security review with no Critical or High findings.
Optional hosted mode. The same app can also run on a small DigitalOcean Droplet, with Gemma from DigitalOcean's Serverless Inference:
- Caddy for HTTPS, and a read-only container;
- no accounts: a device is linked once and remembered;
- a daily cap on model calls;
- a one-command release with short-lived registry credentials and automatic rollback.
It says clearly on screen that Gemma runs at DigitalOcean in that mode. Home mode stays the default.
Why Does Open Innovation Matter?
Because the whole idea depends on it.
- Privacy is the product. The app sees my balcony, my laundry, my habits and photos of my home. With open weights, Gemma runs on my laptop and the photos never leave it. The only outbound call is to Open-Meteo, and the coordinates are rounded. A closed API would need all of it sent to someone else's server.
- I can change the model, not just the prompt. Open weights let me fine-tune the bookmaker with QLoRA on my own GPU, export it to GGUF and serve it in Ollama, then measure base against fine-tuned on a held-out season.
- I can inspect it. I pin the model digest, log every decision and replay a backtest. A model that changes silently behind an API would break the calibration numbers.
- No per-call cost, and it works offline. At home there are no tokens to pay for. If the internet drops, the weather comes from the cache and Gemma keeps working.
-
No lock-in. The same
ModelClientruns Ollama, llama.cpp or a hosted endpoint. When I wanted a public version, I moved to an open-model endpoint without touching a single Gemma job. - It's open all the way down: Gemma 4, Ollama, llama.cpp, Open-Meteo (CC BY 4.0), and Piper for the demo voice.
My Agent Session
This is the session where the idea went from a brief to an approved spec:
From there, the build followed the spec task by task. Each pull request maps to task and requirement IDs, so you can trace any feature back to the acceptance criteria that asked for it.
The Lazy Payoff
Every figure in the app shows its assumption, and savings count only on wins:
| Chore the sky does for you | Saved per win |
|---|---|
| Watering 5 balcony pots | ~5 min, ~4 L of water (typical estimate) |
| Rinsing the car | ~40 min, ~75 L, the low end of a car wash (sourced) |
| Rinsing the terrace | ~15 min, ~30 L (typical estimate) |
| Rinsing the bike | ~10 min, ~20 L (typical estimate) |
For example, if the rain rinses the car twice a month and waters the plants twice a week, that's roughly 2 hours and 185 L of water a month I don't spend (about 1 h 58 min net, because the app subtracts the 30 seconds each bet takes). And when Gemma says "unlikely", I do the chore myself and earn +5 if the sky really wouldn't have helped.
The bigger payoff is the guilt-free part. Doing nothing is now a decision with odds, a receipt and a calibration chart.
Prize Categories
- Overall
- Best Use of Gemma: Gemma 4 E4B runs locally as the decision maker for seven jobs, with tool calling, schema-checked answers, a rule baseline, calibration tracking, a logged "How Gemma decided" trail on every bet, and a QLoRA fine-tune pipeline. Gemma decides; code executes.
@adricasi Adrià Casals Espax
Credits: weather data by Open-Meteo (CC BY 4.0). Gemma 4 by Google. Demo voice: Piper "Ryan" (RyanSpeech, CC BY-NC-SA 4.0). Demo music: original.
Top comments (1)
The details here matter more than the headline, honestly.