This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
What I Built
I don't stay indoors because I don't want to go out. I stay in because two small decisions are easy to put off: when, and to do what. Weather apps tell me what it's like outside. Nothing tells me "go at 18:00, and here's where."
Golden Hour does exactly that, and nothing else:
- Tell it when you're free today. Or don't, and it assumes "from now until sunset".
- It picks your best 20–40 minutes. It reads the hourly forecast and sunset for where you are, scores every possible slot, and explains its choice: "dry", "golden hour", "chilly (13°C)".
- Pick up to three hobbies, like photography, history or coffee outside, and it finds the top 5 real places within walking distance from OpenStreetMap.
- Gemma, an open-weight model running on my own server, writes one line for each place: what to do there, right now, in this light and this weather.
- You get a countdown and a calendar invite with a 10-minute reminder. Then you close it.
It's deliberately not an app you spend time in. Success is closing the tab.
Demo
Try it: https://golden-hour-ahl6.onrender.com
(best on a phone: allow location, or search for your city)
Here's a real plan it made for a morning in central Pune. I picked photography and history, and left my free time empty:
06:30–07:10, 94/100. Dry and calm, and it only loses points for being 26 °C at dawn. Then the five places within a 13-minute walk:
Shaniwarwada, the 18th-century fort, is three minutes away, and Gemma's line for it was "Start with a quick photo of the surrounding architecture to capture the morning ambiance." Two of the lines, for the second park and the memorial, are my hand-written templates: the model's attempts didn't pass the checks I describe below, so the app quietly used safe lines instead.
Code
Tanay3484
/
golden-hour
Your best 20-40 minutes outside today, planned by an open-weight model. Hacktoberfest 2026 'Touch Grass' challenge.
🌅 Golden Hour
Your best 20–40 minutes outside today, and one small thing to do with them.
Tell Golden Hour when you're free. It checks the hourly forecast and sunset for where you are, picks the nicest window to be outside, and finds the top 5 real places within walking distance that suit your hobbies, from OpenStreetMap. An open-weight model (Gemma, served by Ollama) writes one line for each on what to do there right now. You get a countdown and a calendar invite with a 10-minute reminder.
Built for the DEV Hacktoberfest 2026 Open-Source AI Challenge, Week 1: "Touch Grass".
How it works
Browser ──▶ FastAPI ──▶ Open-Meteo (forecast + sunset, open data, no key)
│
├─ scoring.py deterministic: every 20–40 min slot in your free time, scored 0–100
│ (rain, temperature, wind, UV, +15 for golden hour)
│
├─ places.py ──▶ OpenStreetMap (Overpass):…How I Built It
Stack: FastAPI · vanilla JS (about 30 KB, no build step) · Ollama serving Gemma 3 (gemma3:1b in production, gemma3:4b on my laptop) · Open-Meteo for weather and OpenStreetMap for places (both open data, no API keys) · two services on Render.
free time + forecast ──▶ plain Python picks the window (tested, explainable)
hobbies + location ──▶ OpenStreetMap → Python ranks top 5 (no model involved)
window + 5 places ──▶ Gemma writes one line per place (JSON schema, validated)
Building it taught me four things I didn't expect.
1. Let math pick the time. Let the model write.
My first instinct was to hand Gemma the whole forecast and ask "when should I go out?". I didn't, for three reasons: a 1B model on a shared CPU is slow, it's bad at arithmetic over 48 rows of numbers, and I wanted to be able to explain why it chose 18:00.
So the window is picked by under 200 lines of plain, tested Python. Every quarter-hour slot in your free time gets the worst weather of the hours it touches, then a score: start at 100, lose 0.8 points per % chance of rain, 3 per °C outside 15–24, 2 per km/h of wind above 20, 5 per UV point above 6, and gain 15 if it overlaps the hour before sunset. The reasons on the card come from the same list of factors as the score, so the explanation can't disagree with the number.
Writing tests caught a bug no demo would have: on a perfect day every slot scores 100 after capping, so the golden-hour bonus vanished and the earliest slot won. You'd only notice on the one perfect evening you actually wanted. A tie-break that prefers golden hour fixed it.
2. Small models need guardrails, not just better prompts
Gemma only does the creative part, and its answers have to match a JSON schema (Ollama's structured outputs make this reliable even at 1B). Testing it locally on real data was humbling:
| What Gemma did | What fixed it |
|---|---|
| With no location, it sent me to a nonexistent "Elm Street" | It isn't allowed to name places it wasn't given; it describes kinds of places instead |
| At a 70% chance of rain, it suggested an open field | "Match the weather" was too vague. Now the first step must say how to stay dry |
| Asked to "pick the best 5" of 13 real places, it returned the first five in list order. 4B called a Berlin memorial the "Frauenkirche" | Code ranks the places (hobby, walking time, weather, variety). Gemma only describes them, using facts from OpenStreetMap |
| It wrote a park's line about a statue elsewhere on the list | Gemma must echo each place's name, and the server rejects any line that doesn't match, names another place, or borrows another place's facts. Rejected lines become a hand-written template |
The honest result: gemma3:1b now puts every line on the right place, but still adds the odd plausible detail ("a pastry" at a café). gemma3:4b doesn't, but it's about five times slower. On a 1-CPU server, I chose fast, and I wrote the gap down in the spec instead of hiding it.
3. Open data is free, but not effortless
The public OpenStreetMap query servers (Overpass) are a shared, volunteer-run resource. In one evening of testing, two of three public instances failed for every city, and the main one kept answering "server too busy" for Pune and Mumbai while Berlin worked fine.
The first fix was one directive. Overpass decides whether to admit a query based on how much memory it might need, and the default is 512 MB. Declaring 64 MB ([maxsize:67108864]) got Pune through in 3 seconds.
Then I deployed, and the live site found zero places, twelve times in a row. The same query from my home connection returned 44 places in 3 seconds. Overpass limits how many queries each IP address can run, and my Render server shares its outbound IP with a lot of other people's apps. So now, if the server can't reach OpenStreetMap, your browser asks it directly, with the exact same query, and hands the raw results back to the server to rank. Every visitor brings their own rate limit. Anything a browser sends back is treated as untrusted and never cached, so nobody can plant fake places for the next person. If both routes fail, you get a single Gemma-written activity instead, and the page never breaks.
For privacy, OpenStreetMap only ever sees the centre of your ~1 km area. Exact walking times are computed on my server, and nothing is stored.
4. One setting doubled my speed on Render
render.yaml is a two-service Blueprint: a public FastAPI web service, and a private Ollama service with Gemma baked into its Docker image. The web app reaches it over Render's private network, so the model has no public endpoint at all.
The first live run was painfully slow: 38–80 seconds per suggestion, about twice what I'd measured in Docker with the same 1-CPU limit. The cause was one setting. Ollama sizes its thread pool from the host machine's CPU count, so on a big shared server it ran dozens of threads fighting over the single CPU my plan provides. Setting num_thread to 1 doubled the speed: suggestions now usually take 15–30 seconds instead of up to 80. If you run a small model on a small cloud instance, check this first.
Built spec-first, with an AI pair
I built Golden Hour spec-first: requirements with testable acceptance criteria, then a design, then a task list, each approved before any code was written. It's all in specs/. Every task had an owner: me, or my AI pair, Claude Code.
I wrote the first scoring rules myself. Then my GRE landed in the same week, and I handed most of the build to Claude, working from the approved spec while I reviewed and merged. Every change of plan, from the golden-hour tie-break to the browser fallback for OpenStreetMap, went into a spec changelog before it went into the code. So the repo shows why things changed, not just what. It's covered by 154 Python tests, a Node test for the countdown and calendar export, and CI on every pull request.
Why Does Open Innovation Matter?
Because "when are you free" and "where are you" are personal. A closed-API version of this app would send your location and schedule to a third party every time you opened it. Here, the model runs on a server I control and never receives coordinates at all. Weather and places come from open data, with no keys and no accounts.
Because it should be cheap enough to just exist. An app that nudges you outside once a day shouldn't come with a per-token bill or a usage cap. The whole production stack is two small CPU services on Render, about $32 a month, with no metered API anywhere.
Because I got to choose the trade-off. Same code, same prompt: 4B on my laptop for richer lines, 1B in production to fit a small box. Switching is one environment variable. With a closed model, someone else decides the size, the price and whether it's still available next month.
Because you can see why it said 18:00. The scoring rules, the prompts, the guardrails and the model weights are all open. If it ever sends you out into the rain, you can find the exact rule that let it happen, and send a pull request.
What's Next
- An installable phone version with a local "your golden hour starts in 10 minutes" notification, so it reaches you even when the tab is closed
- Running Gemma on the phone itself, so it works offline and fully privately
- The field test I owe this project, right after the GRE
Prize Categories
- Render: Render is the project's AI runtime. Gemma runs on a private Render service via Ollama, behind a public web service, deployed from a one-click Render Blueprint.
-
Gemma: Gemma 3 writes every activity suggestion and every place line:
gemma3:1bin production,gemma3:4blocally, constrained to JSON schemas.



Top comments (1)
Official Platform Update
Security protocols have been updated for all developer accounts.
Some comments have been hidden by the post's author - find out more