<?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: XExpertAI</title>
    <description>The latest articles on DEV Community by XExpertAI (@xexpertai).</description>
    <link>https://dev.to/xexpertai</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%2F4177065%2F92520185-0ef2-4089-a143-959196194fe6.png</url>
      <title>DEV Community: XExpertAI</title>
      <link>https://dev.to/xexpertai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xexpertai"/>
    <language>en</language>
    <item>
      <title>Outside Hour: a local Gemma model that wants you off your phone in 60 seconds</title>
      <dc:creator>XExpertAI</dc:creator>
      <pubDate>Sun, 11 Oct 2026 20:24:05 +0000</pubDate>
      <link>https://dev.to/xexpertai/outside-hour-a-local-gemma-model-that-wants-you-off-your-phone-in-60-seconds-564b</link>
      <guid>https://dev.to/xexpertai/outside-hour-a-local-gemma-model-that-wants-you-off-your-phone-in-60-seconds-564b</guid>
      <description>&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;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Most "get outside" apps want one more scroll. &lt;strong&gt;Outside Hour&lt;/strong&gt; gives itself &lt;strong&gt;60 seconds of your attention&lt;/strong&gt;, and&lt;br&gt;
shows it: a ring in the corner counts down while the page is on your screen. You tell it where you are and how&lt;br&gt;
long you have. A Gemma model running on my laptop picks one real park, lake or garden nearby and writes a pocket&lt;br&gt;
card. When the minute is up, the ring turns red, the page dims and asks you to put the phone down. Then the&lt;br&gt;
screen goes black, and the biggest thing on it is your turn-back time: &lt;em&gt;07:40&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Use it the evening before: plan tomorrow's 7 a.m. walk tonight, so the morning needs no screen at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The card has five things:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Where to go:&lt;/strong&gt; one real place within walking distance, from OpenStreetMap, and what is mapped there (Lotus
Pond and Bamboo Island Pond inside Cubbon Park, 66 mapped trees, 89 benches).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which way:&lt;/strong&gt; a compass arrow with the bearing and the straight-line distance, worked out in code from the
coordinates and labelled "straight line, not a route". No map tiles, no map service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to turn back:&lt;/strong&gt; leave, turn-back and home times, cut short so you're back before sunset.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three things to notice&lt;/strong&gt; at &lt;em&gt;that&lt;/em&gt; place in &lt;em&gt;that&lt;/em&gt; light: the water surface at Lotus Pond, dew and long
shadows at 7 a.m., the sky changing before sunset.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What to bring&lt;/strong&gt; for the forecast: rain, UV, heat, wind, air quality, a torch after dark.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Then three ways off the screen:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Phone down:&lt;/strong&gt; a black screen with the place, the direction and a huge turn-back time, plus two meters: time
&lt;strong&gt;on this screen&lt;/strong&gt; and time &lt;strong&gt;away from it&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Print pocket card:&lt;/strong&gt; an A6-wide card for your pocket, so the phone can stay home.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turn-back alarm (.ics):&lt;/strong&gt; a calendar event whose alarm goes off at turn-back time. The phone's own clock does
the reminding, so the app can be closed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The meters are honest about what a web page can know.&lt;/strong&gt; They use the browser's Page Visibility API: time counts&lt;br&gt;
only while the page is visible, and "away" is the time it has been hidden since you tapped Phone down. It can't see&lt;br&gt;
other apps, and the screen says so.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One rule shaped the design:&lt;/strong&gt; anything that could hurt you if it were wrong (the place, walking times, turn-back&lt;br&gt;
time, direction, sunset, weather) comes from code and open data. Gemma only chooses between real places and&lt;br&gt;
writes the words.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Pocket card&lt;/th&gt;
&lt;th&gt;Phone down&lt;/th&gt;
&lt;th&gt;Printed card&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&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%2Feu8r6q04k7u6khtnvxou.png" alt="Form with the 60-second ring" width="800" height="1731"&gt;&lt;/td&gt;
&lt;td&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%2F78lhmlzmsdijfrmukdmp.png" alt="Pocket card for Cubbon Park" width="800" height="1731"&gt;&lt;/td&gt;
&lt;td&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%2Fcoq0cbuwt44a6k1o2mds.png" alt="Phone-down screen" width="780" height="1688"&gt;&lt;/td&gt;
&lt;td&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%2Fqb2s6xlxjqc6q40hb2jr.png" alt="Printable pocket card" width="800" height="1882"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Real run on my laptop CPU, no GPU, at phone size. The start is MG Road metro station in Bengaluru, a public place&lt;br&gt;
I used as a demo location; the plan is for 60 minutes at 07:00 the next morning, because I made it at night.&lt;br&gt;
Places, times and weather are real OpenStreetMap and Open-Meteo data from 11 October 2026. In the phone-down&lt;br&gt;
screenshot, the 20 seconds "away" come from a simulated phone lock in my recording script (headless browsers never&lt;br&gt;
hide a page); on a real phone, locking the screen does the same thing.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Tsh3luZPPXA" 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/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy68d5wyo1lbcn3ksjvk5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy68d5wyo1lbcn3ksjvk5.gif" alt="Outside Hour: pocket card, the 60-second ring running out, phone down" width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Demo video (81 s, voiceover):&lt;/strong&gt; &lt;a href="https://youtu.be/Tsh3luZPPXA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; (also in the repo as &lt;a href="https://github.com/xexpertai/outside-hour/blob/main/demo/outside-hour-demo-v2.mp4" rel="noopener noreferrer"&gt;outside-hour-demo-v2.mp4&lt;/a&gt;).
The same real phone-size run, framed and zoomed: the 29 s model wait is cut, a few moments are held so you can
read them, and the simulated-lock "away" part runs at 4× speed. All three are labelled on screen. A second real
run (Lalbagh, 45 min, 17:30) closes it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Earlier desktop demo:&lt;/strong&gt; &lt;a href="https://github.com/xexpertai/outside-hour/blob/main/demo/outside-hour-demo.mp4" rel="noopener noreferrer"&gt;51 s, captioned&lt;/a&gt; and &lt;a href="https://github.com/xexpertai/outside-hour/blob/main/demo/outside-hour-demo-realtime.mp4" rel="noopener noreferrer"&gt;73 s, uncut real time&lt;/a&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/xexpertai" rel="noopener noreferrer"&gt;
        xexpertai
      &lt;/a&gt; / &lt;a href="https://github.com/xexpertai/outside-hour" rel="noopener noreferrer"&gt;
        outside-hour
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Outside Hour: one honest plan to get outside, written by a local Gemma model on your laptop. DEV Hacktoberfest 2026 Week 1.
    &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;Outside Hour&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;A pocket card for one short trip outside, from a local Gemma model, on a page that gives itself 60 seconds of
your attention.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Outside Hour looks up real parks, lakes, gardens and viewpoints near you on OpenStreetMap, and what is mapped
inside them (named ponds, trees, benches, drinking-water taps). It checks the weather, sunset and air quality on
Open-Meteo, and asks &lt;strong&gt;Gemma 4 E2B, an open-weight model running on your own CPU&lt;/strong&gt;, to pick one place and write a
short pocket card: where to go, when to turn back, three things to notice there, and what to bring. Then it gets
out of the way: a black "phone down" screen, a printable card, and a calendar alarm for the turn-back time.&lt;/p&gt;
&lt;p&gt;Built for the DEV × Hacktoberfest 2026 Open-Source AI Challenge, Week 1: "Touch Grass".&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Pocket card&lt;/th&gt;
&lt;th&gt;Phone down&lt;/th&gt;
&lt;th&gt;Printed card&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/xexpertai/outside-hour/demo/shots-v2/1-form.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%2Fxexpertai%2Foutside-hour%2FHEAD%2Fdemo%2Fshots-v2%2F1-form.png" alt="Form"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/xexpertai/outside-hour/demo/shots-v2/2-card.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%2Fxexpertai%2Foutside-hour%2FHEAD%2Fdemo%2Fshots-v2%2F2-card.png" alt="Card"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/xexpertai/outside-hour/demo/shots-v2/3-phone-down.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%2Fxexpertai%2Foutside-hour%2FHEAD%2Fdemo%2Fshots-v2%2F3-phone-down.png" alt="Phone down"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/xexpertai/outside-hour/demo/shots-v2/4-print-card.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%2Fxexpertai%2Foutside-hour%2FHEAD%2Fdemo%2Fshots-v2%2F4-print-card.png" alt="Print"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Screenshots are from one…&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/xexpertai/outside-hour" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;MIT licensed. Two scripts download llama.cpp and the model into the project folder (no sudo, no GPU, no API keys).&lt;br&gt;
Tests run offline against recorded data.&lt;/p&gt;

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

&lt;p&gt;About 1,500 lines of standard-library Python plus a one-page HTML and JavaScript front end (no build step, no&lt;br&gt;
CDN), built on four open pieces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fetch.&lt;/strong&gt; One &lt;a href="https://overpass-api.de" rel="noopener noreferrer"&gt;Overpass&lt;/a&gt; query gets every &lt;em&gt;named&lt;/em&gt; park, garden, water body, viewpoint
and footpath within walking range from &lt;a href="https://www.openstreetmap.org/copyright" rel="noopener noreferrer"&gt;OpenStreetMap&lt;/a&gt; (ODbL). A
second, optional query gets what makes a place specific: unnamed ponds, individually mapped trees, benches,
taps, toilets, playgrounds. &lt;a href="https://open-meteo.com" rel="noopener noreferrer"&gt;Open-Meteo&lt;/a&gt; (CC BY 4.0) gives the forecast, sunrise,
sunset and air quality for exactly my time window. Everything is cached, with a proper User-Agent and slow
retries, because the public Overpass servers are shared (I hit plenty of 504s while building this).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute.&lt;/strong&gt; Code works out walking time (4.5 km/h, times 1.3 because paths are never straight), time there,
turn-back time, the sunset cut-off, the light ("early morning", "before sunset"), and the bearing and
straight-line distance to the nearest edge of each place. It also works out what is mapped inside each place's
outline. It skips cemeteries, drains, private land and unnamed spots, and ranks the rest by kind, size and
distance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask Gemma.&lt;/strong&gt; &lt;a href="https://huggingface.co/google/gemma-4-E2B-it" rel="noopener noreferrer"&gt;Gemma 4 E2B-it&lt;/a&gt; (Apache 2.0, Q4_0 GGUF, 2.84 GB)
runs in &lt;a href="https://github.com/ggml-org/llama.cpp" rel="noopener noreferrer"&gt;llama.cpp&lt;/a&gt;'s &lt;code&gt;llama-server&lt;/code&gt; (MIT). It gets the five best
candidates as JSON, each with its named ponds, what else is mapped there and "notice" ideas built from those
features and the light. It returns one &lt;code&gt;place_id&lt;/code&gt;, a headline, a "why", three things to notice and a
phone-down line. The &lt;code&gt;place_id&lt;/code&gt; is an &lt;code&gt;enum&lt;/code&gt; in a JSON schema, so it &lt;em&gt;cannot&lt;/em&gt; pick a place I didn't fetch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check.&lt;/strong&gt; A validator rejects the draft if it names a place that isn't in the map data, talks up a different
place, uses a number or clock time that isn't in the facts, mentions water or a view the map doesn't support,
uses stock filler ("offers a pleasant spot"), or looks cut off. One retry, then a plain template. Every card
says who wrote it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Two bugs that taught me how Gemma 4 behaves on a CPU
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Thinking skipped the grammar.&lt;/strong&gt; Through the chat endpoint, Gemma 4 sometimes "thought" for 400 tokens before
writing any JSON, and the grammar never kicked in: about 47 seconds, no answer. Rendering the chat template myself
(llama-server's &lt;code&gt;/apply-template&lt;/code&gt;) and sending it to &lt;code&gt;/completion&lt;/code&gt; put the grammar on the very first token. Since
then, every answer in my benchmark has been valid JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Length limits cut sentences.&lt;/strong&gt; A &lt;code&gt;maxLength&lt;/code&gt; in the schema doesn't make the model write shorter; it stops it
mid-word. One early line ended "…focus on the" plus a stray Korean character. I loosened the limits, asked for
"one sentence under 15 words", and added checks for cut-off text and non-English characters. The turn-back time
is now added by code, so the model can't get it wrong.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Making a 2B model specific
&lt;/h3&gt;

&lt;p&gt;My first cards were true but bland: "Enjoy the park's shade and greenery" (from my first benchmark, &lt;code&gt;docs/bench-results.json&lt;/code&gt;). The model only knew a place's name and&lt;br&gt;
kind, so that was all it could say. The fix was better facts, not a longer lecture. Each candidate now arrives&lt;br&gt;
with its named ponds, what OpenStreetMap maps inside it (trees, benches, a tap; without counts, so it doesn't&lt;br&gt;
quote survey numbers), and notice ideas that depend on those features and on the light. Now the same model writes&lt;br&gt;
"Look at the water surface for one full minute at the Lotus Pond" for Cubbon Park at 7 a.m. The checker learned&lt;br&gt;
too: "pond" is allowed only when the map has water there, and a short list of stock phrases is rejected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measured on my laptop
&lt;/h3&gt;

&lt;p&gt;Intel Core i5-1035G1 (4 cores, 8 threads, 2019), no GPU, 10 GB RAM, WSL2. Ten plans from &lt;code&gt;scripts/bench.py&lt;/code&gt;&lt;br&gt;
(2 cities, 3 start points, 30–90 minutes, morning to evening), on cached map data, with the current prompt:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measure&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Plans written by Gemma (not the fallback template)&lt;/td&gt;
&lt;td&gt;10 of 10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drafts rejected by the checker&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time per plan, median (min–max)&lt;/td&gt;
&lt;td&gt;28.7 s (24.0–32.3 s)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt, median&lt;/td&gt;
&lt;td&gt;~1,250 tokens (~860 new, the rest reused from cache), processed at 55 tokens/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output, median&lt;/td&gt;
&lt;td&gt;134 tokens at 9.7 tokens/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cards that mention something mapped at the chosen place&lt;/td&gt;
&lt;td&gt;7 of 10 (a simple word match)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;llama-bench&lt;/code&gt; prompt / generation, 4 threads&lt;/td&gt;
&lt;td&gt;61.9 / 9.4 tokens/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llama-server memory after a plan&lt;/td&gt;
&lt;td&gt;about 4.3 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The richer prompt costs about 4 seconds per plan compared with my first version (median 24.8 s). The laptop was&lt;br&gt;
doing other work too, so times vary. Using the 4 physical cores was a little faster in my runs than all 8 threads&lt;br&gt;
(generation 9.4 vs 7.5 tokens/s, but noisy), so the start script uses physical cores.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Open weights let me control the model, not just prompt it.&lt;/strong&gt; With a closed API I could only &lt;em&gt;ask&lt;/em&gt; the model not&lt;br&gt;
to invent places. With Gemma in llama.cpp I made choosing an unfetched place impossible with a grammar, switched&lt;br&gt;
off thinking to make it fast enough on a CPU, and saw exact token counts and speeds for every call. When thinking&lt;br&gt;
bypassed the grammar, I could find out why, because every layer is open: the model card, the chat template and the&lt;br&gt;
server source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's free to run, so it has no reason to keep you.&lt;/strong&gt; Places and weather come from open data with no keys, and&lt;br&gt;
the model runs on my laptop. No account, no subscription, no per-plan bill. Many apps are paid for with your&lt;br&gt;
attention; this one is happiest when you close it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No AI company sees where you are.&lt;/strong&gt; "Where are you, and when are you free?" is personal. The model that reads it&lt;br&gt;
runs on my machine. The only network calls are the open-data lookups (coordinates rounded to about 100 m for&lt;br&gt;
OpenStreetMap and 1 km for Open-Meteo), and they're cached, so a recently fetched area can be planned with&lt;br&gt;
&lt;code&gt;--offline&lt;/code&gt; and no connection at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open map data knows the small places.&lt;/strong&gt; OpenStreetMap has the Bamboo Island Pond inside a Bengaluru park and the&lt;br&gt;
Sopan Baug garden in Pune because volunteers mapped them. Commercial places APIs tend to put businesses first.&lt;br&gt;
OpenStreetMap is a map made by people who walk.&lt;/p&gt;

&lt;p&gt;It's also swappable: any chat model llama.cpp can run can replace Gemma by pointing &lt;code&gt;MODEL_FILE&lt;/code&gt; at another GGUF file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Walking times are estimates (straight line × 1.3), not real routing, and the arrow is a straight line too. Big
parks are measured to the edge of their bounding box.&lt;/li&gt;
&lt;li&gt;It only knows what OpenStreetMap knows. Unnamed places are skipped, and opening hours aren't enforced. "Mapped
here" uses each place's bounding box, so it can include things just beside it.&lt;/li&gt;
&lt;li&gt;Gemma 4 E2B (about 2B effective parameters) is now specific but sometimes stiff ("The water surface is
present"). The checker stops invented facts; it doesn't make the writing brilliant.&lt;/li&gt;
&lt;li&gt;About 29 s on my CPU once the area's map data is cached. The first plan in a new area also waits for
OpenStreetMap (up to about 15 s in my runs). That wait is screen time; plan the evening before, or look away.&lt;/li&gt;
&lt;li&gt;The 60-second budget measures this page, not your phone.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How AI helped
&lt;/h2&gt;

&lt;p&gt;An AI coding assistant (Claude) helped me plan and build this. It drafted most of the code, the tests and a first&lt;br&gt;
version of this post. I reviewed the design rules (code computes every fact, the model only chooses and phrases,&lt;br&gt;
and every card says who wrote it), ran the app on my laptop, checked the numbers against the benchmark files and&lt;br&gt;
edited the text. The product itself uses no closed or paid AI: only Gemma, running locally.&lt;/p&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 4 E2B runs on a 2019 laptop CPU at under 30 s a plan, and because the weights and
chat template are open, I could render the template myself, switch thinking off and put a JSON grammar on the
first token. Result: in two 10-plan benchmarks, all 20 plans were written by Gemma (no template fallback), and
the model can't name a place I didn't fetch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Map data © OpenStreetMap contributors (ODbL). Weather and air quality: Open-Meteo.com (CC BY 4.0).&lt;/em&gt;&lt;/p&gt;

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