<?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: Bhavye Kathuria</title>
    <description>The latest articles on DEV Community by Bhavye Kathuria (@thebhavye).</description>
    <link>https://dev.to/thebhavye</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%2F4159838%2Ff04575af-741f-4089-ab16-f57018ac82e5.jpg</url>
      <title>DEV Community: Bhavye Kathuria</title>
      <link>https://dev.to/thebhavye</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thebhavye"/>
    <language>en</language>
    <item>
      <title>Kerbside: walk your street, talk about what's broken, get a map (Whisper + Gemma, fully offline)</title>
      <dc:creator>Bhavye Kathuria</dc:creator>
      <pubDate>Sun, 11 Oct 2026 20:41:55 +0000</pubDate>
      <link>https://dev.to/thebhavye/kerbside-walk-your-street-talk-about-whats-broken-get-a-map-whisper-gemma-fully-offline-3pp5</link>
      <guid>https://dev.to/thebhavye/kerbside-walk-your-street-talk-about-whats-broken-get-a-map-whisper-gemma-fully-offline-3pp5</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;"Every evening I walk past a road on my campus that has been dug up for weeks, with red poles and tape across it. Everyone walks around it; nobody reports it."&lt;/p&gt;

&lt;p&gt;Everyone in an Indian city knows the footpath problems on their street. Almost nobody reports them, because reporting is tedious: stop, take a photo, open a portal, pick a category, type a description, pin a location, repeat. So complaints, when they happen at all, sound like "the roads near my house are bad", and nothing gets fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kerbside turns a walk into a complaint report.&lt;/strong&gt; You walk your street with your phone in your pocket, saying what you see out loud:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I can see some red poles here for a barricade."&lt;br&gt;
"The road is not fully built, some stones here and there."&lt;br&gt;
"Huge rain tree here, nice shade."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your phone records a voice memo and a GPS track with free apps. Back home, Kerbside runs &lt;strong&gt;entirely on your laptop&lt;/strong&gt;, with open models only, and turns them into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;a map&lt;/strong&gt; of every problem (and every good thing) at the spot you mentioned it,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;a one-page report&lt;/strong&gt; for a ward office or a complaint portal, most severe first, each item with a map link and the resident's own words,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;a spreadsheet&lt;/strong&gt; for portals and groups that want a table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A person reviews everything before it goes anywhere. Kerbside saves you the hour of typing; it doesn't file complaints on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it touches grass:&lt;/strong&gt; most touch-grass apps get &lt;em&gt;you&lt;/em&gt; outside. Kerbside makes your walk useful to everyone who walks that street after you. The only input it accepts is a walk, so there is no way to use it from your desk, and the screen comes &lt;em&gt;after&lt;/em&gt; you've been outside, for a few minutes of review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who it's for:&lt;/strong&gt; residents, resident welfare associations, students and NGOs who do walkability audits. Not everyone needs to install it: residents only record on their phones, and one organiser with a laptop processes the walks and shares the map link.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/kS0uZ0Ri-40" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live map of my walk:&lt;/strong&gt; &lt;a href="https://thebhavye.github.io/kerbside/demo/map.html" rel="noopener noreferrer"&gt;https://thebhavye.github.io/kerbside/demo/map.html&lt;/a&gt; (open it on your phone)&lt;/p&gt;

&lt;p&gt;This is my real 12-minute evening walk on campus on 11 October: a voice memo and a GPS track from my iPhone, processed on my laptop, then reviewed by me.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fmp31n2q66h3lhf0sx45b.png" class="article-body-image-wrapper"&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%2Fmp31n2q66h3lhf0sx45b.png" alt="The Kerbside app's review screen with Gemma's 11 draft findings" width="800" height="383"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Before review: Gemma's 11 draft findings, with my words under each one.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2F11bw8kbyu7zhafxujdma.png" class="article-body-image-wrapper"&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%2F11bw8kbyu7zhafxujdma.png" alt="The review screen after I deleted the mishearings" width="800" height="383"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;After review: 6 real problems left.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fvnc7zrzq7evupcd3cvgp.png" class="article-body-image-wrapper"&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%2Fvnc7zrzq7evupcd3cvgp.png" alt="The shared map on a phone with a finding open" width="780" height="1520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A finding from the generated report:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Road dug up for construction and barricaded with tape, on the road by Just Bake and Enzo.&lt;/strong&gt; · moderate (2/3) · 18:30 · &lt;a href="https://www.openstreetmap.org/?mlat=12.972590&amp;amp;mlon=79.158960#map=19/12.972590/79.158960" rel="noopener noreferrer"&gt;map&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Resident's words: "I can see some red poles here for a barricade. So it looks like some construction is going on. Okay, there is a full construction going on. They have put some tapes like barricades."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the phone map, tap a circle and then &lt;strong&gt;Copy complaint text&lt;/strong&gt; to paste a ready-made complaint into WhatsApp or a portal.&lt;/p&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/thebhavye" rel="noopener noreferrer"&gt;
        thebhavye
      &lt;/a&gt; / &lt;a href="https://github.com/thebhavye/kerbside" rel="noopener noreferrer"&gt;
        kerbside
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Walk your street, talk about what's broken, get a map. Runs fully on your laptop with Whisper and Gemma.
    &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;Kerbside&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Walk your street, talk about what's broken, get a map. Everything runs on your own laptop.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://thebhavye.github.io/kerbside/demo/map.html" rel="nofollow noopener noreferrer"&gt;Live demo map&lt;/a&gt;&lt;/strong&gt; · &lt;a href="https://github.com/thebhavye/kerbside/demo/report.md" rel="noopener noreferrer"&gt;demo report&lt;/a&gt;
(a real 12-minute evening walk on a college campus: voice memo and GPS from an iPhone, processed by Whisper
and Gemma on a laptop, then reviewed by the walker. Kerbside drafted 11 findings; review removed 5
mishearings and corrected the rest.)&lt;/p&gt;
&lt;p&gt;You walk your street with your iPhone in your pocket, recording a voice memo and a GPS track. Kerbside
transcribes what you said with &lt;a href="https://github.com/SYSTRAN/faster-whisper" rel="noopener noreferrer"&gt;faster-whisper&lt;/a&gt;, uses
&lt;a href="https://ai.google.dev/gemma" rel="nofollow noopener noreferrer"&gt;Gemma&lt;/a&gt; running in &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt; to pick out the street
problems you mentioned ("footpath broken here", "drain blocked", "streetlight not working") and the good
things ("huge rain tree, nice shade"), places each one on your walked route, and gives you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;map.html&lt;/code&gt;: a phone-friendly map of everything you found, with a place search box&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report.md&lt;/code&gt;: a one-page report ready…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/thebhavye/kerbside" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;MIT licensed. Python, no cloud services, no API keys.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;voice memo (.m4a) ─┐
                   ├─► 1. work out when the recording started
GPS track (.gpx) ──┘   2. faster-whisper: speech → timestamped sentences
                       3. each sentence → a point on the GPS track
                       4. Gemma 3 (4B) in Ollama: sentences → findings
                       5. map + report + GeoJSON + CSV
                       6. a person reviews and edits, then shares
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything runs on a &lt;strong&gt;Windows laptop with an Intel i5, 16 GB of RAM and no GPU&lt;/strong&gt;, either from the command line or from a small local web app (&lt;code&gt;python kerbside.py --app&lt;/code&gt;) where you drop in the two files, watch progress, and review findings on a map. The app only listens on &lt;code&gt;127.0.0.1&lt;/code&gt;, so nothing leaves the machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speech: faster-whisper on CPU
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/SYSTRAN/faster-whisper" rel="noopener noreferrer"&gt;faster-whisper&lt;/a&gt; runs the &lt;code&gt;small&lt;/code&gt; model in &lt;code&gt;int8&lt;/code&gt; on the CPU and skips the silence between observations. An 8.5-minute recording transcribes in about 30 seconds.&lt;/p&gt;

&lt;p&gt;One bug taught me something. With silence skipping on, Whisper placed one sentence &lt;strong&gt;66 seconds&lt;/strong&gt; before it was spoken, because after a long pause a segment's start can snap back to the end of the previous speech. At walking pace that's about 80 metres of error. Taking each sentence's time from its &lt;strong&gt;first word&lt;/strong&gt; (&lt;code&gt;word_timestamps=True&lt;/code&gt;) fixed it.&lt;/p&gt;

&lt;p&gt;Each sentence's time is then matched to the GPS track. If the nearest GPS fix is more than 30 seconds away, the finding is flagged "location approximate" and drawn with a dashed outline, so the reviewer checks it first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gemma: from "list the findings" to "label every line"
&lt;/h3&gt;

&lt;p&gt;This is where most of the work went. Gemma 3 4B runs in &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; with &lt;strong&gt;structured outputs&lt;/strong&gt;: the request includes a JSON schema, so the model can only answer with valid categories and severities.&lt;/p&gt;

&lt;p&gt;My first version asked Gemma for a list of findings from each chunk of 12 sentences. On a held-out set it &lt;strong&gt;lumped three unrelated lines into one finding and skipped others&lt;/strong&gt;, and two identical runs gave different answers. A small model given a list to fill in will happily skip lines.&lt;/p&gt;

&lt;p&gt;So I changed the question. Gemma now &lt;strong&gt;labels every single line&lt;/strong&gt;: a problem category, a good thing, "same as previous" (a follow-up like &lt;em&gt;"someone could trip on this"&lt;/em&gt;) or "not an observation" (&lt;em&gt;"ok, turning left"&lt;/em&gt;). The code merges follow-ups into one finding. Three details that each fixed a real failure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Numbering lines 1..n in every chunk.&lt;/strong&gt; Gemma kept renumbering lines 13–15 as 1–3, and the code threw away correct answers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Summary before severity in the schema.&lt;/strong&gt; Ollama generates fields in order, so the model describes the problem before rating it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A severity floor in code.&lt;/strong&gt; Gemma kept rating an open drain as "moderate". Open drains, missing covers, manholes and holes are now always "severe". A fixed rule is more predictable than more prompt tuning.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What my first real walk taught me
&lt;/h3&gt;

&lt;p&gt;All of that was tested on scripted walks. Then I did a real one, and it broke in a way my tests never did.&lt;/p&gt;

&lt;p&gt;Real people don't only name problems. They narrate: &lt;em&gt;"there is a lot of greenery on this road"&lt;/em&gt;, &lt;em&gt;"on the left I have the back side of a shop, where you can buy chips"&lt;/em&gt;, &lt;em&gt;"I see a tennis court"&lt;/em&gt;. On my 12-minute walk, Gemma produced &lt;strong&gt;47 findings&lt;/strong&gt;, and about 40 of them were scenery.&lt;/p&gt;

&lt;p&gt;Adding more "don't count this" rules to the prompt barely helped. What worked was making Gemma &lt;strong&gt;commit to a simple decision first&lt;/strong&gt;: for every line it now says what &lt;em&gt;kind&lt;/em&gt; of line it is (a problem, praise, a description of the surroundings, or chatter) before it labels it, and the code drops any category attached to a description or chatter line. Two more rules moved from the prompt into plain code: a line right after a finding that names no new street thing (&lt;em&gt;"about two feet wide"&lt;/em&gt;, &lt;em&gt;"full construction going on"&lt;/em&gt;) joins that finding, including across chunk boundaries, where my unfinished-road finding had been split in two.&lt;/p&gt;

&lt;p&gt;The same walk now gives &lt;strong&gt;11 findings&lt;/strong&gt;. Six are real: construction material, the barricaded road, cut trees, the unfinished road. The other five came from Whisper mishearing me: "volleyball court" became "vulnerable court", and a building I named became "a chair block", which Gemma reasonably reported as a chair blocking the footpath. In the review screen I deleted those, fixed the wording, and moved two findings to where I actually saw them. &lt;strong&gt;47 → 11 → 6.&lt;/strong&gt; That's the split I want: AI drafts, the person who walked there decides.&lt;/p&gt;

&lt;p&gt;My GPS track taught me something too. The tracker app didn't have background location permission, so it stopped when my phone locked and logged only the first and last minute of the walk. That's why the report says 143 m walked and most points are marked "location approximate". Kerbside flagged every guess instead of quietly inventing positions, and the README now tells you to set location access to "Always" before you walk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measuring it
&lt;/h3&gt;

&lt;p&gt;An evaluation script runs real Gemma on test sets with expected answers: my sample walk, a held-out set I never tuned against, split sentences, and my real walk. On the final version the three scripted sets get &lt;strong&gt;every category right, with nothing missed and nothing extra&lt;/strong&gt;. Severity is sometimes one level off, and Gemma occasionally treats a detail like "pole number seventeen" as chatter, which is why there's a review step.&lt;/p&gt;

&lt;p&gt;Speed on the i5: Gemma takes &lt;strong&gt;about 1–2 minutes per 12 sentences&lt;/strong&gt;, so my 96-sentence walk took about 12 minutes. Kerbside shows a time estimate and unloads Gemma when it's done, to give the RAM back. (Lesson learned the hard way: ten forgotten background processes holding 15 GB of memory will make any local model crawl.)&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Because a voice recording plus a GPS track is a map of your life.&lt;/strong&gt; It shows where you live, when you leave home and the route you walk, in your own voice. I would not ask a neighbour to upload that to a company's API to report a pothole. With open-weight models, Kerbside never has to: Whisper and Gemma run on the laptop, and only the findings you've reviewed get shared. (For this post, my walk's full transcript stays off the public repository; only the six reviewed findings are public.)&lt;/p&gt;

&lt;p&gt;Open models also make it &lt;strong&gt;free to run, forever&lt;/strong&gt;. A residents' association has no budget for API credits, and a tool that stops working when a free tier ends is worse than no tool.&lt;/p&gt;

&lt;p&gt;And open means &lt;strong&gt;adaptable&lt;/strong&gt;. The categories, severity rules and prompt live in one readable Python file, so a group in another city can add "stray cattle" or "no ramp for wheelchairs" without asking anyone's permission. The output is open data (GeoJSON and CSV), not locked in someone's dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fully in the browser:&lt;/strong&gt; small Gemma and Whisper models can already run inside a web page on the visitor's own device. Same privacy, zero install.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ward audits:&lt;/strong&gt; several residents walk different streets, and one organiser combines their reviewed findings into one ward map and one joint report.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Before and after:&lt;/strong&gt; re-walk the same street a month later and get a report of what was fixed and what's still broken. Accountability is the missing half of civic complaints.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I built Kerbside with the help of an AI coding assistant (Claude Code), which helped me spped up coding while I walked, recorded, tested on my own laptop and phone, and reviewed the results. The design decisions and this write-up's claims are mine to stand behind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Gemma.&lt;/strong&gt; Gemma 3 4B, running locally in Ollama, is the part of Kerbside that understands what the resident said. For every transcribed sentence it decides what kind of line it is, labels it with a category, writes the complaint summary and rates severity, all through Ollama's structured outputs so its answers always fit the schema. Per-line labelling, the "decide the kind first" step, the evaluation sets including a real walk, and the deterministic rules around the model all came from making a 4B model reliable enough for a civic report on a CPU-only laptop.&lt;/p&gt;

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