This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass

At 18:27 on Sunday, a machine at Lidl in Galway printed me a voucher for €0.30: two cans at 15 cents each. It's the first deposit I've claimed in two years of living in Ireland. I don't buy drinks. I carry water in a flask.

The cans weren't mine. I picked them up on a walk that an open-weight model planned for me, along with six other bits of litter that paid nothing at all.

There's a story going round 9GAG about someone in Germany who paid for a PS5 with deposit bottles. I couldn't verify it. My number is easier to check, and I kept the voucher.

TL;DR. Return Route plans a walk through the spots where cans and bottles get left behind, and ends it at a deposit return machine. When you get back, one photo of your haul and Gemma counts it. The refund comes from the deposit table, never from the model. Gemma can run in the cloud, on your laptop, or (untested yet) in your phone's browser. I took it on a real walk in Galway: about an hour outside, 8 pieces of litter picked up, 2 that paid, €0.30. You can keep the money or give it away.

What I Built

Ireland has had a deposit return scheme, Re-turn, since February 2024. A can or a small bottle carries 15c, a big bottle 25c, and you get it back from a machine at the supermarket. So every can in a hedge is a refund nobody claimed.

Return Route turns that into a reason to go outside:

  1. Pick how long you've got: 30 minutes, an hour, 90 minutes or your own time. You can add a note like "finish at Tesco, stay off the main road".
  2. Gemma plans a loop through the places where drinks get left behind (picnic tables, pitches, viewpoints, benches near an off-licence) and finishes at a return machine. You get a range for what you might make, never a promise.
  3. Put the phone away. The route goes to Google Maps, and a short briefing is read aloud: where you're going, what to look for, one safety tip.
  4. Back home, take one photo. Gemma counts the containers, says which ones the machine will refuse (crushed, damaged, no deposit mark) and prints an itemised voucher. Then you keep the money, or switch on Walk for a cause: the app turns green, the refund goes to a cause you name, and Gemma drafts a post to get others walking.

Four phone screens from the live app: pick your time on yellow waymark signs, a planned loop on a dark map with three stops and an estimate of €1.22 to €4.02, an itemised voucher for a photographed haul totalling €1.05, and a green thank-you screen for €1.05 given to the local food bank

Screens from the live site: a real plan from Terryland Forest Park on Gemma 26B, then the app's sample haul photo. That photo is generated, with deposit stickers added so the marks are readable.

The screen is on at the start and at the end. In between, it's Google Maps in your pocket and your eyes on the ground. That was the rule I designed around: the app's job is to get you out the door and then get out of the way.

It's for people who walk anyway and would like the walk to do something: dog walkers, students, anyone who joins a local cleanup. I volunteer on weekend cleanups in Terryland Forest Park, which is why the demo starts there.

It covers Ireland's Re-turn and 18 other European deposit schemes, each with its own rates and rules. Return Route is unofficial and not affiliated with Re-turn or any scheme operator.

Demo

The full walk, from planning at home to the voucher, filmed on Ray-Ban Meta glasses and my phone (12 minutes, with chapters):

The one-minute version:

Try it: return-route.onrender.com. It runs on Render's free tier, so the first load after a quiet spell takes about 50 seconds.

Not in Europe? Open return-route.onrender.com/?demo, or tap the demo button on the home screen. The guided demo plans a real walk from Terryland Forest Park with Gemma, plays it on the map, then shows the actual haul from my walk and the voucher it earned. It never touches your own totals.

I took it outside

Sunday 11 October, east Galway, 15°C and overcast. Times are Irish time.

  • 17:26: Planned a 90-minute walk at home, with Gemma 4 26B in the cloud. The app's guess: €1.05 to €3.85.
  • 17:30: Out the door. No gloves. (Bring gloves.)
  • Before I'd left the house: a Monster can with the Re-turn logo, not crushed. 15c.
  • On the road: a crushed can (the machine refuses crushed ones, but it's still litter, so it went in the bag), a wrapper, and an off-licence the planner had scored as a hotspot.
  • Stop 1, the park: spotless. I did find a playground five minutes from home I'd never seen.
  • Between stops: a big bottle, damaged, so it pays nothing. Then a Strong Power can in a hedge: the first real score of the day. A squashed Coca-Cola can and a carton.
  • Stop 2, the skate park: busy with kids, so I left it to them. A glass bottle stayed in the bush: glass isn't in Re-turn, and it's not something to handle bare-handed.
  • Stop 3: Google Maps led me to a college fence with no way in. It was getting dark and the last stop was far, so I headed for Lidl. My guess on camera: "about 30 cents".
  • 18:19: I photographed the haul. The laptop tier failed first, because the laptop was at home. The cloud tier read it: 2 cans, deposit mark not visible, the crushed cans and the bottle struck off. €0.00 for sure, up to €0.30.
  • 18:27: The Re-turn machine took 2 cans. Voucher: €0.30. The top of Gemma's range, exactly my guess, and well below the app's estimate.

Four frames from the walk: a can pulled from a hedge, a fence around a college with no way in, the haul in a black bag, and Gemma's reading on the phone: €0.00 for sure, up to €0.30

The Re-turn machine's screen at Lidl: 2 containers, deposit total €0.30, with paper voucher, digital voucher and donation buttons

What I said outside Lidl, unscripted: "the open source project that I just made is working very well … we touched grass, I hope that counts."

What the walk taught me

  • My neighbourhood is cleaner than the planner thought. It guessed €1.05 to €3.85 and I made €0.30. I'll take that as good news about east Galway. It's also exactly what the app's hotspot history is for: every logged walk shifts the estimate for the stops you visited.
  • The stops were the quietest part. The cans were in hedges, on walls and along the road near the off-licence, not at the picnic tables. The planner's starting scores favour parks, and on a clean Sunday the park was clean.
  • A stop behind a fence is a dead end. The map said there was something worth visiting; it didn't say you can't get in.
  • Photo close, labels up. From above, in a bag, Gemma couldn't confirm the small Re-turn logos. The + button fixed the count by hand.
  • Crushed doesn't pay. Pick them up anyway.
  • Bring gloves.

What I changed after the walk

No more stops behind a school gate. Pitches and picnic tables inside school or childcare grounds, and anything mapped as private, are no longer stops, unless the map marks that pitch as open to the public. University campuses stay in, because they're usually open. When I checked the map data for east Galway afterwards, 17 pitches and 6 picnic tables were inside school grounds; the city snapshot had 51 more school pitches and a school playground. They're gone now.

The first version still leaked 6 pitches when the map came from vector tiles. A place near the edge of a tile also appears in the next tile's margin, and that tile only carries a sliver of the school's outline, so the check passed. Each place is now read only from the tile it's actually in.

Code

Return Route. An hour's walk, €0.30. Gemma plans the litter loop, code counts the money. A real walk in Galway, and the Lidl deposit voucher to prove it.

Return Route

A walk that pays. Gemma plans a loop through the spots where cans and bottles get left behind,
and ends it at a deposit return machine. Keep the refund, or give it away.

Live app Guided demo Full walk video MIT

Gemma 4 Mastra Render Sentry Hacktoberfest

Ireland's Re-turn scheme pays 15c for a can or a small bottle and 25c for a big one, so every can in a hedge is a refund nobody claimed. Return Route turns that into a reason to go outside. Tell it how long you've got. It plans a walk past picnic tables, pitches and viewpoints near off-licences, gives you an honest range for what you might make, hands the route to Google Maps, and then gets out of your way.

When you're back, take one photo of your haul. Gemma counts the containers, flags the ones the machine will refuse and works out your refund from the deposit table. Keep the money, or switch to…

MIT licensed, built during the challenge week, with 54 tests. If you only read six files, read these:

File What it does
src/lib/ai/guard.ts Every rule Gemma can't break: real stops only, no money talk, no bins
src/lib/countries.ts 19 deposit schemes, and the only place money comes from
src/mastra/workflows/planWalk.ts The planning workflow, with map, weather and events in parallel
src/lib/plan/overpass.ts OpenStreetMap places, minus anything behind a school gate
src/lib/ai/edge.worker.ts Gemma 4 E2B in the browser on WebGPU (untested on a phone)
src/lib/privacy.ts What Sentry never sees: coordinates, IPs, cache keys

Run it on your own laptop:

ollama pull gemma4:e4b git clone https://github.com/MuhammadMurtuzaHussain/return-route && cd return-route && pnpm install cp .env.example .env.local # MODEL_PROVIDER=ollama pnpm dev # http://localhost:3100 

How I Built It

Gemma judges, code guarantees

A small model will sometimes invent a park, promise you a fiver, or tell you to go through the bins. So I split the work. Gemma does the parts that need judgement. Plain code owns everything that has to be right, and Gemma can't override it.

Gemma decides Code guarantees
Which stops, in what order, and why each one Every stop is a real place from the map, and the walk fits your time
What's in the photo: material, size, mark visible, crushed or not What it pays, from the deposit table
What to look for, and one safety tip The place names in the spoken briefing
One opening line for your post The count, the amount and the cause in that post

Gemma picks from a list of real places, and a stop it invents is dropped. A route that's too long is trimmed against the real walking path. Money never comes from the model: any sentence where Gemma mentions an amount is removed before it's shown or read aloud.

/** Gemma's words are read aloud; they must not promise money the app did not compute. */ export function stripMoney(s: string): string { return s .split(/(?<=[.!?])\s+/) .filter((sentence) => !/[€£$]\s?\d|\d+\s?(euro|eur|cent|kr|zł|ft)\b/i.test(sentence)) .join(" ") .trim(); } /** Bins belong to the people who rely on them. Keep "leave bins alone", drop "look in the bins". */ export function leaveBins(s: string): string { return s .split(/(?<=[.!?])\s+/) .filter((sentence) => !/\bbins?\b|pfandring/i.test(sentence) || /\b(leave|don'?t|do not|never|avoid|not)\b/i.test(sentence)) .join(" ") .trim(); } 

The walk showed why the split matters. Gemma couldn't see the deposit marks in my bag photo, so it didn't guess. It reported "mark not visible", and the code turned that into a range: €0.00 for sure, up to €0.30. The machine paid the top of it. When a model that handles money can't see, I want it to say so, and this one did.

That split is also what should let a 2B model in a phone's browser do the same job as a 26B model in the cloud.

One model family, three places

Where Model Where your haul photo goes
In the cloud Gemma 4 26B-A4B through Google AI Studio To Google
On your laptop Gemma 4 E4B through Ollama Nowhere: it stays on your laptop
In your phone's browser Gemma 4 E2B on WebGPU (transformers.js), about 3.4 GB once Nowhere: it's read on the phone

You pick in Settings. The prompts, the guard and the deposit table are the same for all three.

The phone tier is untested. The code is in the repo and the production build bundles the worker and the WebGPU runtime, but I haven't had an Android phone to run it on, so I can't tell you how long the download takes or how fast it plans. Treat it as the part I'd test first.

Planning needs open map, weather and routing services (OpenFreeMap, Open-Meteo, Valhalla), so your start point goes to those whichever tier you pick. What changes between tiers is where your photo and the model's work go.

The planner: a Mastra workflow

place ──► map ║ weather ║ events ──► assemble ──► pick ──► route │ │ │ │ │ │ │ deposit OSM Open- SerpApi score Gemma Valhalla walking scheme POIs Meteo (optional) hotspots picks & route, trimmed for the orders until it fits country 2-3 stops 

The map, the weather and today's events are fetched in parallel. The score is a hotspot prior for each kind of place, times yesterday's weather (a warm evening leaves cans behind), the day of the week, any match or gig nearby, and your own past hauls. Nobody has a live litter feed, so the estimate starts as an honest guess and gets sharper with each walk you log. That history stays on your device. There are no accounts.

If your country has no deposit scheme, the first step stops the workflow with a plain message instead of planning a walk that can't pay. On the phone tier, the server runs the first half of the same workflow, Gemma picks the stops in a Web Worker, and the server checks and routes the result.

Here's one plan from the live site, as Sentry traced it. The Gemma call is 7.2 of the 8.7 seconds:

A Sentry trace waterfall of one plan: the plan-walk workflow with its place, map, weather, events, assemble, pick and route steps; inside pick, invoke_agent Return Route planner and chat gemma-4-26b-a4b-it take 7.2 seconds, and route calls Valhalla in 0.75 seconds

Measuring it

I wrote 8 Galway walks (different starts, lengths and notes like "finish at Lidl" or "stay off the main road") and ran them through both server tiers before and after tightening the planner:

Tier Plans the guard didn't touch Too long Invented stop Finished where asked Time per plan
Cloud, 26B-A4B, before 7/8 1 0 4/5 5.2 s
Cloud, 26B-A4B, after 8/8 0 0 5/5 5.3 s
Laptop, E4B, before 6/8 2 0 4/5 5.7 s
Laptop, E4B, after 7/8 0 1 5/5 5.4 s

The fix was mostly code, not prompting: for every return point on offer, the planner works out which stops still fit if the walk ends there, a shop you name becomes the finish, and two stops in the same field get distinct names. The one stop E4B invented was caught and dropped.

To be clear about what this measures: it shows Gemma follows the rules. It doesn't show the stops have cans. Only walking tells you that, and on my one walk, the park was clean.

The haul reader has an eval harness too (pnpm eval), but only one real haul so far: the bag from this walk. Both server tiers read it as 0 eligible, because the marks were too small from above. The real answer was 2. That's why the camera screen says "labels up, nothing stacked", and it's the first thing I'll measure properly.

When the cloud gets turned away

Locally, everything worked. On Render, planning failed. Sentry showed why: every Overpass mirror was answering the server with errors, and the place lookup and weather service were returning 429. Render's free tier sends traffic from IP addresses shared by many apps, and public map servers rate-limit them. A laptop never sees that.

Sentry breadcrumbs for the failed plan: overpass.private.coffee and overpass.kumi.systems both answering 500, then the error Overpass unavailable

So the map now has a chain of fallbacks:

  1. Render Key Value, which caches each neighbourhood for 12 hours.
  2. A bundled OpenStreetMap snapshot of Galway, so the demo never waits on a map server.
  3. OpenFreeMap vector tiles from a CDN. A 30-minute area took 1 to 2 seconds in Galway, Berlin, Copenhagen, Amsterdam and Vienna. Return machines come from Overpass alongside, with a 6-second budget.
  4. Full Overpass.
  5. The walker's own browser, which fetches the map from their connection and plans again.

The side effect is that plans now work anywhere in Europe, not just in Galway. The whole service is one render.yaml Blueprint: the web service and the Key Value cache, deployed on every push to main.

The ReturnRoute Blueprint in Render: return-route (Node, deployed) and return-route-cache (Valkey 8, available), synced from the GitHub repo's main branch

What Sentry sees, and what it shouldn't

Every Gemma call is an agent span with the model, tokens and latency, so I can see the planner and the haul reader side by side. Prompts and replies are never sent: the Input tab is empty on purpose.

Sentry's agent view: the Return Route planner and the Return Route haul checker, both on gemma-4-26b-a4b-it; the planner call took 7.20 s with 1.9K tokens in and 227 out, and its Input tab says no input for this span

Every time the guard overrules Gemma, that's an issue tagged with the tier and the model. The one at the top of the guard list is real: E4B planned a route too long for the time. The three below it I triggered on purpose, to check that the phone tier's picks are guarded and reported too.

Sentry issues: two Overpass unavailable errors from the Render outage, and four guard issues: Gemma's route didn't fit the time, a return point that wasn't on the map, a stop that wasn't on the map, and none of Gemma's stops were real

And then I found my own walk in it. Taking screenshots for this post, I searched the traces and found 415 weather spans from the last two weeks with the walker's position in the URL: latitude=53.2845&longitude=-9.0420, accurate to about 10 metres, from both the browser and the server. The cache spans were worse: the rate limiter's key held the walker's IP address, and the map cache's key held rounded coordinates. I had a privacy block in the Sentry config, and it didn't cover either.

The fix is one small file shared by the browser, server and edge configs. URLs lose their query strings, and cache keys are cut down to their kind:

/** "https://api.open-meteo.com/v1/forecast?latitude=53.28…" → "https://api.open-meteo.com/v1/forecast" */ const URL_QUERY = /(https?:\/\/[^\s?#"]+)\?[^\s#"]*/g; /** "incr rr:rl:plan:<ip>:29862636" → "incr rr:rl"; "get rr:area:v2:53.28,-9.04,2500" → "get rr:area" */ const CACHE_KEY = /\b(rr:[a-z]+)(?::[^\s"]*)?/g; 

After it deployed, I planned a fresh walk on the live site and opened its trace. The weather span now reads GET https://api.open-meteo.com/v1/forecast, the rate limiter's span reads incr rr:rl, and there isn't a coordinate or an IP anywhere in it. The spans sent before the fix will age out with Sentry's retention.

Things that went wrong

  • Gemma sent people into bins. It suggested checking bins for bottles. In Germany, people leave bottles on a Pfandring for those who collect deposits for a living. leaveBins drops any sentence about bins unless it says to leave them alone.
  • Titles like "Park Waste Collection" and "Eyre Square Park Run". A title now has to name a real place on the route, and "run" becomes "loop".
  • "Based on the image, I have identified 7 containers." The narration is stripped before the voucher shows Gemma's notes.
  • Cities that map every bin ranked "Bins (4)" as their best stop. Street furniture is now capped, and bins only count inside a park.
  • Two stops called "Pitch, Wildflower Meadow". Look-alikes are now "east end" and "west end", and the briefing never says the same park twice.
  • Map markers drifted 30, 60 and 90 pixels down the page. Setting position on a custom MapLibre marker overrides its own positioning. Don't.
  • A school outline cut off at a tile edge let pitches inside school grounds through (above).
  • My privacy block had gaps (above).
  • Gemma 4 E4B overcounts busy hauls by about one. The voucher shows every item, so you can correct it before it counts.

Why Does Open Innovation Matter?

When the payout is 15 cents a can, the AI has to cost nothing. A walk that earns €0.30 can't pay for API calls. On a laptop, Gemma costs nothing per plan and nothing per photo, so the maths of the whole idea only works with an open model.

Your photo doesn't have to leave your device. On the laptop tier, the haul photo is read by Gemma on your own machine. The phone tier is built to do the same in the browser, though I haven't tested it on a phone yet. Your walk history stays in your browser too: there are no accounts. A walk history is a map of where you live and when you're out. It shouldn't sit on someone else's server, and after this week, it doesn't sit in my Sentry either.

I could build a box around the model. Gemma runs inside my own pipeline, so every output passes through code I wrote and tested before anyone sees it. The same family runs at three sizes in three places, so I wrote the prompts and the guard once, and Sentry tells me which size breaks which rule.

It's open all the way down. Map data from OpenStreetMap, tiles from OpenFreeMap, walking routes from Valhalla, weather from Open-Meteo, the workflow on Mastra, the phone model on transformers.js. None of them needs a key. The only part that does is the optional cloud tier.

Where a closed model might do better: reading small logos on crumpled cans in a bag. I haven't tested one, so I can't say it would. Both Gemma sizes I tried missed the marks on my real haul, and the honest fix so far is a better photo, not a bigger model.

What it can't do yet

  • The hotspot scores are educated guesses. They're based on what tends to attract drinkers (benches, pitches, off-licences), and my one real walk says roadsides beat parks.
  • Reading deposit marks from a bag photo is unreliable. Close up, labels up, it works. From above, in a bag, it doesn't.
  • The phone tier is untested on a real phone.
  • Europe only: 19 schemes. The UK's starts in October 2027. US states with bottle bills aren't in yet.
  • Free hosting: the first plan after a quiet spell waits about 50 seconds for Render to wake up.

My Agent Session

I built Return Route with Claude Code over three days, across five sessions: from reading this challenge, through the brain dump that became the PRD, the redesign, the Render outage, the videos, to the fixes in this post. This is a curated version: my prompts trimmed, Claude's turns summarised, and the tool calls real.

Building Return Route with Claude Code: from a brain dump to a €0.30 voucher
You

Look into the Week 1 challenge, and get back to me when you have understood it. I am thinking of an idea meanwhile.

Agent

Read the Week 1 brief. Touch Grass: build something with open-source AI at its core that gets people off the screen and into the world, and make the screen the shortest part of it. Submissions close Sun 11 Oct, 23:59 PDT. Writing quality is weighted most, taking it outside earns bonus points, and you can win only one prize category.

▸ get_challenges DEV challenges
DEV challenges
Hacktoberfest Open-Source AI Challenge: Week 1, 5 to 11 Oct. Featured: Render, TabPFN, Tinker, Arduino, DigitalOcean, Gemma. Partner: Mastra, Sentry Agent Tracing and 8 more.
You

Here's my unedited brain dump. Categorize it into a PRD and tell me how the plan looks for the vision I have in mind. The persona is a student, an early-career person or just a young adult, who likes to walk around and explore the city but would also like a bit more change in their pocket. One easy way to get extra coins is collecting cans and bottles and sending them into the return machine. This is inspired by a story of a person in Germany who picked up about 2,000 bottles, turned them in for 500 euro and bought a PS5. Can my app give people a good, predictable path around parks and the usual hotspots where they can pick up cans and litter? Focus on Ireland, because that's where I know the return scheme works, and other European countries with a scheme, plus the UK.

Show more
Agent

Wrote the PRD for "Return Route": say how long you've got, get a loop through likely hotspots that ends at a return machine, with an honest € range, then put the phone away. Checking the facts changed the plan: the UK scheme only starts in October 2027, so v1 is Ireland plus other live European schemes. The PS5 story is a viral 9GAG post with no outside confirmation, so the post should call it unverified. Re-turn pays 15c up to 500 ml and 25c above, only for cans and PET bottles with the logo, and the machines refuse crushed ones. Other Week 1 entries are already walk planners, so the edge is the money.

Show more
▸ WebSearch Germany man collected 2000 bottles Pfand bought PS5
Germany man collected 2000 bottles Pfand bought PS5
Only the viral post itself; treat it as an unconfirmed viral story.
▸ WebSearch UK deposit return scheme launch date England Scotland 2027
UK deposit return scheme launch date England Scotland 2027
October 2027, 20p per container.
▸ search_dev_to_semantic walking route planner with OpenStreetMap and open source routing
walking route planner with OpenStreetMap and open source routing
Paper Walk and other Week 1 walk planners.
You

I like everything. Can we run a small-weight model locally, for an edge AI use case? If so, let's build that, as well as cloud Google AI Studio. Scope: Ireland and other European countries with a return scheme. Donate mode: keep it in v1. Solo. Keep this project polished and ambitious, we need to win.

Agent

Built the MVP with Gemma in three places: E2B in the browser on WebGPU through transformers.js, E4B through Ollama, and 26B-A4B through AI Studio, with a Mastra planner and a deposit table for 19 European schemes. The rule from day one: Gemma picks stops from a list of real places and explains them; code drops invented stops, trims long routes, composes the spoken place names and prices everything, and stripMoney removes any amount Gemma writes. Public Overpass servers kept failing, so Galway ships as a saved OpenStreetMap snapshot. The phone tier builds but hasn't run on a phone.

▸ Bash Fetch and save Galway OSM snapshot
$ Fetch and save Galway OSM snapshot
Overpass unavailable: overpass.private.coffee → 500 (4 attempts)
▸ Bash Retry Galway snapshot with new mirrors
$ Retry Galway snapshot with new mirrors
galway: 536 features, 210 sources, 25 parks, 19 return points (4 mapped machines)
▸ Bash Test cloud Gemma tier from Terryland
$ Test cloud Gemma tier from Terryland
→ Aldi return machine 4.06 km, €0.88 to €3.15
▸ Bash Run unit tests
$ Run unit tests
Tests 25 passed (25)
You

Pushed to GitHub, add the render.yaml file so I can deploy. Once that's done, we need to rework the UI/UX using the taste skill and other stuff...

Source:https://dev.to/muhammadmurtuzahussain/i-walked-an-hour-for-30-cents-gemma-plans-litter-walks-that-end-at-a-deposit-machine-4ih9

Related posts