This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
TL;DR Pagdandi is an open database of 20 Indian treks, every fact sourced, with a trek guide that runs on Gemma on a laptop.
Tell it who's going, the budget, the days and where you start; it picks treks you can actually do, and code checks every number it says.
Then it gets out of the way: a half-minute audio intro, a one-page plan, and one email a day until you leave.
What I Built
Every city has this group chat. Five college friends in Delhi NCR (a composite of groups we all know) have been saying "is baar pakka trek chalenge" ("this time we're definitely going on a trek") for three years. Different budgets, two first-timers, and nobody wants to be the one who plans it.
Pagdandi (पगडंडी, "footpath") is for them. Four ways in:
Ask the guide. "5 of us, 2 first-timers, ₹12k each, 4 days in December, from Delhi." The answer is a few sentences and a card per trek, nearest first.

The cards, the altitude note and the next steps come from the database, not from the model.
Browse the table. All 20 treks, plain filters, an audio intro in every row, and a "weak source" mark on any fact with only one shaky source.
Open a trek. Sources for every fact, an altitude warning above 3,500 m, a plan that prints on one page, and an audio intro to download for the drive.
Get daily updates. Sign up with the travel date and get one email a day until you leave: the forecast at the road head and the high point, the week's headlines with links, and one thing to do outside today. Until Pagdandi has a domain, only the admin gets them.

This morning's real email for Kedarkantha. Open-Meteo's forecast and a SerpApi news search feed it; this week the search found nothing, so it says so.
Taking it outside

Kedarnath, on our recent trip, before Pagdandi existed.
This photo is from Kedarnath, where my friends and I went recently: cloud sitting on the snow peaks, and the slopes green from the monsoon. Kedarnath is a pilgrimage walk, and it isn't one of Pagdandi's 20 treks yet. We didn't use Pagdandi on that trip either. It didn't exist.
That trip was the exception. Most of the time we're the group from the top of this post. We plan the next one at our desks, the chat stalls on "which one can all of us actually do?", and nobody gets up.
Pagdandi is built for that moment: ten minutes to agree on a trek, then the phone goes in a pocket, with the intro downloaded and the one-page plan printed. And because the data is open, every group that plans with it can leave it better for the next one. Kedarnath is the natural first addition, by pull request, sourced like every other trek.
Demo
Watch the demo (2½ minutes, plays on GitHub): the guide, the table, a trek page and its plan, then a sign-up and the email.
There's no hosted copy: Pagdandi runs on a laptop. Running your own takes about 10 minutes, plus the model download:
brew install ollama postgresql@17 pgvector node@24 pnpm
git clone https://github.com/prateek11rai/pagdandi && cd pagdandi
pnpm install && cp .env.example .env # set ADMIN_EMAIL; the rest has working defaults
pnpm dev:up # starts Postgres and Ollama if they aren't running
ollama pull gemma4:e4b && ollama pull embeddinggemma:300m
pnpm treks:load && pnpm treks:embed
pnpm dev # http://localhost:3000
Code
prateek11rai
/
pagdandi
India's open trek database: pick a trek your group can actually do, then put the phone away.
Every friend group has a trek it has talked about for years, and a group chat where "this time we're definitely going" never turns into a date. Pagdandi (पगडंडी, "footpath") is for that group. Tell it how many of you there are, who has trekked before, the budget, the days, the month and where you're starting from, and it recommends treks you can actually do, from 20 well-known Indian treks with every fact sourced. Then it gets out of the way: an audio intro for the drive, a one-page plan for the trail. It runs on a laptop, model included, and anyone can run their own copy.
Watch the demo (2½ minutes, 6 MB): the guide, the table with its audio intros, a trek page and the one-page plan, then a sign-up and the daily email.
Pagdandi-demo.mp4
What you get
-
Ask the guide. "5 of us, 2 first-timers, ₹12k each…
How I Built It

Solid boxes run on the laptop; dashed boxes are hosted services.
-
Gemma 4 on the laptop.
gemma4:e4bruns through Ollama on the machine that serves the site, so a chat costs nothing and never reaches a model company. EmbeddingGemma (768 dimensions) turns treks and questions into vectors. The app refuses a remote Ollama unless you opt in. -
Mastra runs the agent, with four read-only tools:
searchTreks,getTrek,getConditionsandrecommendTreks. The server builds the agent's options from text-only, length-capped messages, so a browser can't swap the prompt or raise the limits. -
Tiger Data holds one Postgres: the treks, a hybrid index (a generated
tsvectorplus a pgvector column, fused with reciprocal rank fusion), conditions, subscriptions and the API budget counters. - SerpApi finds the week's Google News for each followed trek, only from the daily job and behind hard daily and monthly caps. Gemma adds one "What matters" line on top; the reader still sees every headline.
- ElevenLabs voiced all 20 intros once, from scripts I wrote by hand from each trek's sourced facts. The MP3s are committed, so the site serves them itself and they play offline.

Voiced by ElevenLabs from the trek's sourced script. Listen to the Kedarkantha intro (32 s) or the Valley of Flowers intro (30 s).
Audio intros generated with ElevenLabs.
The rule I cared about most: the model never shows a number unchecked. A guide that confidently says "Kedarkantha is 4,200 m" is how people get hurt.
- Cards render database values, never the model's.
- Every sentence the model streams is checked in code before it leaves the server. Altitudes, days, distances and rupees must match the data for the trek it names, or the user's own numbers; anything else becomes "(see the card)".
- The altitude note above 3,500 m comes from the UI, not the model.
- A red-team suite runs real Gemma against prompt injection, off-topic requests, treks we don't have and a request for its instructions. When CI caught Gemma copying its rules, a guard went in that replaces any sentence copying eight words in a row from them.
// simplified from src/lib/fact-check.ts: one pattern (altitude, days, distance or rupees) at a time
for (const m of sentence.matchAll(re)) {
const value = toNumber(m[1]!, m[2]);
const ok =
ctx.userNumbers.includes(value) ||
treks.some((t) => matches(kind, value, t));
spans.push({ start: m.index!, end: m.index! + m[0].length, ok });
}
Every fact is sourced. Each trek is a YAML file, and the schema rejects any fact no source names. Agents drafted the 20 from Wikipedia, Wikivoyage, OpenStreetMap, UNESCO and government pages, with trekking companies off limits, and a second pass re-checked every number. What can't be sourced stays null, and the site says "not known yet".
Why Does Open Innovation Matter?
- Plans stay on the machine. Budgets, dates and who's never trekked go to a model on the laptop, not to a model company. Chats aren't stored.
- No per-chat bill. Anyone can run a copy for their own friends.
-
We could shape the model's job. Open weights and a local runtime let me turn thinking off when it ate the token budget, and run the smaller
e2bon CI's CPU runner. - The data is open too. CC BY-SA trek files that anyone can fix or extend by pull request, with CI validating every source.
Hosted services see a little: SerpApi trek names, ElevenLabs the scripts, Open-Meteo coordinates, Tiger Data the search queries and the admin's subscription; the email leaves from the admin's own mailbox. None of them sees the chat.
What I Got Wrong
- Thinking mode ate the answers. Gemma spent its whole budget reasoning and never answered. Off, it answered in under 3 seconds.
- "First-timers" meant "easy only". That ruled out every moderate beginner trek. The search now takes a maximum difficulty and says which limit the closest matches miss.
- Textbook hybrid search lost to a stray word. Every trek says "trek" and "day", so "short trek near Delhi" ranked Nagaland first. Dropping words found in most documents, and fusing fewer results, fixed it.
- Gemma judged the news, and missed what mattered. It skipped a temple near Ghangaria, the base for the Valley of Flowers, closing for the season, and an earthquake in Uttarkashi. Now the email shows every headline, and Gemma only adds one line.
- The facts I couldn't find. No open source names Kedarkantha's winter months, so a December search misses it. "Never guess" has a cost.
My Agent Session
The curated build session, from the scaffold to the first real email, with the commands that ran and their output:
Prize Categories
- Best Use of Gemma: Gemma 4 runs the guide and the news line; EmbeddingGemma powers search. Both on the laptop, through Ollama.
- Best Use of Tiger Data: pgvector plus full-text hybrid search for the agent, with conditions, subscriptions and budget counters in the same Postgres.
-
Best Use of SerpApi: each trek's weekly headlines in the daily email and the agent's
getConditionstool, behind hard caps. - Best Use of ElevenLabs: a half-minute intro for every trek, voiced once from a sourced script and served for the trail.
- Best Use of Mastra: a Mastra agent over an open model, with read-only tools, structured recommendations and streaming chat.



Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.