<?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: Chitresh Ranjan</title>
    <description>The latest articles on DEV Community by Chitresh Ranjan (@chitresh_ranjan_71e499366).</description>
    <link>https://dev.to/chitresh_ranjan_71e499366</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%2F4167132%2Febe7de32-3dee-435f-8731-3f5967316765.png</url>
      <title>DEV Community: Chitresh Ranjan</title>
      <link>https://dev.to/chitresh_ranjan_71e499366</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chitresh_ranjan_71e499366"/>
    <language>en</language>
    <item>
      <title>Paper Trail: a local AI turns a walk into a puzzle hunt</title>
      <dc:creator>Chitresh Ranjan</dc:creator>
      <pubDate>Mon, 12 Oct 2026 06:45:36 +0000</pubDate>
      <link>https://dev.to/chitresh_ranjan_71e499366/paper-trail-a-local-ai-turns-a-walk-into-a-puzzle-hunt-pc1</link>
      <guid>https://dev.to/chitresh_ranjan_71e499366/paper-trail-a-local-ai-turns-a-walk-into-a-puzzle-hunt-pc1</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;My first scouting recording said I had visited 36 places. I had visited 13.&lt;/p&gt;

&lt;p&gt;Paper Trail turns a voice recording of a walk into a puzzle hunt for that route. I walk a loop with a voice recorder running and, at each stop, say what the sign says and one thing I can see. At my desk, local models turn the recording into a list of stops. Code finds a real word that the signs' letters spell in walking order, Gemma writes a clue for each stop, and the tool prints a sheet for each team. Players follow the clues, read one letter off the right sign at each place and write down the word. A check number on the sheet tells them if they misread something.&lt;/p&gt;

&lt;p&gt;Two friends walked the first hunt on Sunday morning, one per team. They finished in 20 and 18 minutes and wrote the right letters on the first try.&lt;/p&gt;

&lt;p&gt;I scout by voice because the open map data for my campus is thin, so whatever the hunt knows about the place, I said out loud. It suits anyone who wants a reason to walk somewhere they think they already know, as long as the loop has printed signs: friends, a class, a run club.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ranjanchitresh926-sys.github.io/paper-trail/" rel="noopener noreferrer"&gt;Try the demo page&lt;/a&gt;&lt;/strong&gt;: an interactive page on an invented route. Read a sample team sheet, fill in the letters and get the check number, then type a wrong word into the debrief and see which stop it points at. The models don't run in the page, because they need a GPU laptop, and my real route stays private. The checking logic does run in the page, and I tested it against the Python code on 300 random words.&lt;/p&gt;

&lt;p&gt;A line of a team sheet looks like this (real clue wording from my hunt, place name left out):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clue 2   A white house is behind a low stone wall with a black gate.
         Write the last letter of the sign whose name has 18 letters.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The check number is a sum. Team 1's word was STAIN: S=19, T=20, A=1, I=9, N=14, which adds up to 63. Subtract 26 twice and you get 11, the number printed on their sheet. If a team's total doesn't match, a letter is wrong or a sign has changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/ranjanchitresh926-sys/paper-trail" rel="noopener noreferrer"&gt;Paper Trail on GitHub&lt;/a&gt;&lt;/strong&gt;: 42 tests that run without any model, so the checks are easy to rerun. The README has the commands.&lt;/p&gt;

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

&lt;p&gt;Everything runs on one laptop (RTX 5050 with 8 GB of video memory), with no internet once the models are downloaded.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scout.&lt;/strong&gt; A voice recorder in my pocket. At each stop I say: "Stop 4. Sign: the exact words printed. I see: one fixed visible detail." The silence between stops becomes the walking time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transcribe.&lt;/strong&gt; Whisper (small) through faster-whisper on the GPU, with word timestamps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structure.&lt;/strong&gt; Gemma 4 (E4B, through Ollama) turns the transcript into a list of stops, constrained to a JSON schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compose.&lt;/strong&gt; Each stop yields a letter by a simple rule (first letter, last letter, second letter and so on). A dynamic-programming search over about 10,000 common words finds the ones the stops can spell in walking order. Each team gets a different word, and every word gets a check number.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the clues.&lt;/strong&gt; Gemma writes a clue from my description of the stop, and a second and third Gemma pass check it (more on that below).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Print and debrief.&lt;/strong&gt; One sheet per team, an organiser key, and a debrief command that compares what a team wrote with the key and points at the stop that probably changed or was misread. It also gives the check number the wrong word would have produced.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The rule I held to: the models propose and write, and code decides anything that can be checked. A sign has to appear in the transcript. A stop counts as unsafe only if I said so. A description I never gave is dropped. The word is spelled by real letters from real signs, so a solvable hunt is guaranteed. No hunt passes through a stop marked unsafe.&lt;/p&gt;

&lt;p&gt;Two small pieces did most of the work. The Whisper settings that stopped it hallucinating, and the check number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;segments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transcribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word_timestamps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;vad_filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;vad_parameters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_silence_duration_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;speech_pad_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;condition_on_previous_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What broke
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Whisper looped while I walked in silence.&lt;/strong&gt; The first recording gave 696 words and 36 stops for a route with 13. The same sentence came back every 30 seconds, and the loops had overwritten two real stops. A voice-activity filter and turning off conditioning on the previous text gave 238 words and 13 stops, including the two that had gone missing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The clues described things that weren't there.&lt;/strong&gt; The first build wrote 21 clues in 32 attempts and dropped 10 candidate words. At least six of the ten clues that shipped contained details I never gave: "weathered brick", "near the curb", "metal swings just beyond the green expanse", "where travelers gather". My solver pass had approved all of them. It only proves that a clue can be told apart from the other stops, not that it is true. The fix was a stricter writer prompt, a code check for colours, materials and positions the description never used, and a separate Gemma pass that lists anything the description doesn't support. The second build wrote 10 clues in 10 attempts with no invented details. The price is that the clues are now plain and stay close to my own words, and I tidied the grammar of four of them by hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"The sign" was ambiguous.&lt;/strong&gt; One building had its own sign and a department sign inside it, so a player could read the wrong one and write the wrong letter. Every rule now says "the sign whose name has 18 letters".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma guessed a hazard.&lt;/strong&gt; My extraction prompt mentioned road crossings, and the model marked a walkway unsafe, which would have split the route in two. Now only hazard words I actually say count, and the model's guess becomes a question for me.&lt;/p&gt;

&lt;p&gt;Smaller ones: Whisper wrote "sign" as "Sain" in every stop, so I strip it before computing letters. My descriptions were about people and purpose ("where students..."), which nobody can see from a path, so the tool flags them and I rewrote each one as something visible. One team's first stop was about 15 minutes' walk from the printed start, so each team now gets its own start place and honest total minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taking it outside
&lt;/h3&gt;

&lt;p&gt;On Sunday morning two friends walked the hunt, one friend per team, both starting together at about 10:00. Team 1 finished in 20 minutes and Team 2 in 18. Both wrote the right letters on the first try, and both check numbers matched.&lt;/p&gt;

&lt;p&gt;They opened the sheets on their phones rather than printing them, so I can't call it a screen-free walk, and I didn't measure screen time. They said the clues were fine and the walk was easy because they know the campus well. They also turned it into a friendly race to the finish, and it wasn't a fair one: Team 1's route was longer on paper (about 18 minutes of walking against 15.5), so next time I'll equalise route lengths.&lt;/p&gt;

&lt;p&gt;It was a small test with two people who know the place. Next I want to print the sheets, measure screen time properly, and try it on someone who has never been there.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;My voice and my route stayed on my laptop.&lt;/strong&gt; The recording is me describing a real place. Nothing was uploaded, and the pipeline runs offline once the models are downloaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could change how the models behaved when they failed.&lt;/strong&gt; I changed Whisper's decoding settings to stop the loop, constrained Gemma's output with a schema, and turned off its thinking mode, which took replies from up to about two minutes to roughly 2.5 seconds in my tests. I reran clue generation as often as I needed at no cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could see every failure.&lt;/strong&gt; The looping transcript, the invented "brick" and the false hazard flag were all in files on my disk, so I fixed them with settings and checks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I didn't compare against a hosted model, so I'm not claiming it beat one.&lt;/strong&gt; What the open pieces gave me is privacy, control and zero running cost.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;Best Use of Gemma.&lt;/strong&gt; Gemma 4 (E4B) runs locally and does four jobs: it structures the scouting transcript, writes the clues, judges whether a clue is supported by my description, and acts as the solver that checks each clue points to a single place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;Thanks to two friends who walked the hunt and told me honestly how it went. I built Paper Trail with an AI assistant (Claude) as a pair programmer: the design, code and tests came out of long conversations with it. I did the scouting, checked every sign against the real boards, made the editing decisions, and ran the field test with my friends.&lt;/p&gt;

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