<?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: Aritro Bag</title>
    <description>The latest articles on DEV Community by Aritro Bag (@dev-aarish).</description>
    <link>https://dev.to/dev-aarish</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%2F3982873%2Fe478c6c0-7867-425e-9f69-8d7e2ebb8bc8.jpg</url>
      <title>DEV Community: Aritro Bag</title>
      <link>https://dev.to/dev-aarish</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dev-aarish"/>
    <language>en</language>
    <item>
      <title>I Trained an Open Tabular AI to Catch the 72-Hour Fall Foliage Peak (So You Can Keep Your Phone in Your Backpack)</title>
      <dc:creator>Aritro Bag</dc:creator>
      <pubDate>Mon, 12 Oct 2026 05:14:30 +0000</pubDate>
      <link>https://dev.to/dev-aarish/i-trained-an-open-tabular-ai-to-catch-the-72-hour-fall-foliage-peak-so-you-can-keep-your-phone-in-lb0</link>
      <guid>https://dev.to/dev-aarish/i-trained-an-open-tabular-ai-to-catch-the-72-hour-fall-foliage-peak-so-you-can-keep-your-phone-in-lb0</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 autumn, millions of outdoor enthusiasts scramble to catch peak fall foliage. It is one of the most breathtaking natural spectacles on earth—and one of the most frustrating to time. The window of true peak vibrancy lasts roughly &lt;strong&gt;72 hours&lt;/strong&gt; before cold rains and wind strip the canopy bare.&lt;/p&gt;

&lt;p&gt;To catch it, hikers currently face two bad options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Coarse, paywalled tourism maps:&lt;/strong&gt; Coarse statewide county-level blobs sponsored by regional hotel boards that completely ignore elevation, microclimate valleys, and specific tree canopy species.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screen-addicted trail apps:&lt;/strong&gt; Outdoor apps that demand you keep staring at a glass rectangle on the trail, buzzing with notifications, draining battery in cold weather, and demanding constant GPS screen time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I built &lt;strong&gt;Wander&lt;/strong&gt;: an open phenology forecaster and zero-screen trail companion. &lt;/p&gt;

&lt;p&gt;Wander is designed around a radical &lt;strong&gt;Zero-Screen Philosophy&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&amp;lt; 30 seconds on screen:&lt;/strong&gt; Open the web app, let the tabular foundation model calculate the exact 72-hour peak color window calibrated to trail elevation and canopy mix.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;At the trailhead:&lt;/strong&gt; Listen to a &lt;strong&gt;45-second natural audio briefing&lt;/strong&gt; outlining terrain, weather conditions, and tree species to look out for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On the trail:&lt;/strong&gt; Carry a &lt;strong&gt;1-page printable pocket field card&lt;/strong&gt; folded into your shirt pocket. Your phone stays zipped away inside your backpack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best technology for the outdoors is the one that gets out of the way.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Web App:&lt;/strong&gt; &lt;a href="https://wander-web-rg30.onrender.com" rel="noopener noreferrer"&gt;https://wander-web-rg30.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Documentation &amp;amp; Healthcheck:&lt;/strong&gt; &lt;a href="https://wander-api-7t4f.onrender.com/docs" rel="noopener noreferrer"&gt;https://wander-api-7t4f.onrender.com/docs&lt;/a&gt; · &lt;a href="https://wander-api-7t4f.onrender.com/health" rel="noopener noreferrer"&gt;&lt;code&gt;/health&lt;/code&gt;&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/dev-Aarish" rel="noopener noreferrer"&gt;
        dev-Aarish
      &lt;/a&gt; / &lt;a href="https://github.com/dev-Aarish/wander" rel="noopener noreferrer"&gt;
        wander
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &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;Wander 🥾&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Open Phenology, Fall Peak Foliage Forecaster &amp;amp; Zero-Screen Trail Companion&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://dev.to/t/hf26challenge" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/20804e5769df6b66ecd1257bc281408d64c41a6af606f095adf4dfa0ac0f2ba0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4861636b746f626572666573742d323032365f5765656b5f313a5f546f7563685f47726173732d6666373834392e737667" alt="Hacktoberfest 2026"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://fastapi.tiangolo.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d934b63851de931fc75fab09a150907e741053f735ed432ef4b5c1bf942e10dc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466173744150492d312e302e302d3030393638382e737667" alt="FastAPI"&gt;&lt;/a&gt;
&lt;a href="https://priorlabs.ai" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6189f6335bbf6a1f0b402951148e09f5e444c2b0ff79c3c482fc1cb2fe243b10/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54616250464e2d5072696f725f4c6162732d626c75652e737667" alt="TabPFN"&gt;&lt;/a&gt;
&lt;a href="https://tigerdata.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e44babeeb7b3d5cce24fffc36270c8cabfb35c583000c765cb7ed55f83ce7d36/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54696765725f446174612d506f737467726553514c5f2532425f7067766563746f722d6f72616e67652e737667" alt="Tiger Data"&gt;&lt;/a&gt;
&lt;a href="https://temporal.io" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d66a0195342bf05bd5e9f24eed063d51f514c0a852c43f4d0d82037179be3dd4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54656d706f72616c2d44757261626c655f576f726b666c6f77732d626c61636b2e737667" alt="Temporal"&gt;&lt;/a&gt;
&lt;a href="https://elevenlabs.io" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6f39359877d17aced25e322e4ede27c70f5c13b0466030e77ae8f35574664d31/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f456c6576656e4c6162732d566f6963655f53796e7468657369732d6461726b677265656e2e737667" alt="ElevenLabs"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Built for the DEV Hacktoberfest 2026 Challenge: Week 1 — Touch Grass (&lt;code&gt;#hf26challenge&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;"The best builds here should make the screen the shortest part of the experience."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;💡 The Problem &amp;amp; The Zero-Screen Solution&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Every autumn, millions of hikers scramble to catch the elusive &lt;strong&gt;72-hour peak foliage window&lt;/strong&gt;. Existing solutions are either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Coarse, paywalled tourism statewide maps that lack elevation accuracy.&lt;/li&gt;
&lt;li&gt;Clunky smartphone apps that require constant screen checking on the trail, ruining the immersion of nature.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Wander&lt;/strong&gt; is built on a radical &lt;strong&gt;Zero-Screen Philosophy&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&amp;lt; 30 seconds on screen:&lt;/strong&gt; TabPFN computes the exact 72-hour peak window from micro-weather physics, elevation, and canopy species.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;At the trailhead:&lt;/strong&gt; Listen to a &lt;strong&gt;45-second ElevenLabs audio briefing&lt;/strong&gt; outlining terrain, weather, and key species.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On the trail:&lt;/strong&gt; Carry a &lt;strong&gt;1-page printable pocket field card&lt;/strong&gt;. Your phone stays…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dev-Aarish/wander" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  The Biophysical Phenology Engine
&lt;/h3&gt;

&lt;p&gt;Plant phenology (the timing of cyclical biological events like autumn leaf senescence) isn't a text generation problem. It is an environmental physics problem governed by thermal chill hours, solar photoperiod shortening, elevation lapse rates, and drought stress.&lt;/p&gt;

&lt;p&gt;Rather than asking an LLM to guess dates, Wander couples &lt;strong&gt;TabPFN (Prior Labs)&lt;/strong&gt; with calibrated bioclimatic formulas derived from U.S. Forest Service and NOAA meteorological datasets:&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="c1"&gt;# backend/app/services/phenology_model.py:107
# Base day of peak for baseline temperate hardwood forest calibrated to mid-October
&lt;/span&gt;&lt;span class="n"&gt;base_peak_doy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;285.0&lt;/span&gt;

&lt;span class="c1"&gt;# Hopkin's Bioclimatic Law: ~0.8 days shift per degree north, ~0.9 days per 500m elevation
&lt;/span&gt;&lt;span class="n"&gt;lat_shift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;42.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
&lt;span class="n"&gt;elev_shift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;elevation_m&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;500.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;500.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;

&lt;span class="c1"&gt;# Species thermal sensitivity offset (Aspen vs Sugar Maple vs Red Oak vs Larch)
&lt;/span&gt;&lt;span class="n"&gt;species_offset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;canopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quaking_aspen_pct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;canopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alpine_larch_pct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;canopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sugar_maple_pct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;canopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paper_birch_pct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;canopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;red_oak_pct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;canopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;american_beech_pct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;total_canopy_weight&lt;/span&gt;

&lt;span class="c1"&gt;# Chill hours acceleration threshold (~350 hours cumulative below 7°C)
&lt;/span&gt;&lt;span class="n"&gt;chill_hours_norm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chill_hours_cumulative&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;350.0&lt;/span&gt;
&lt;span class="n"&gt;chill_factor_shift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chill_hours_norm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;

&lt;span class="n"&gt;target_peak_doy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base_peak_doy&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;lat_shift&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;elev_shift&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;species_offset&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;drought_shift&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;chill_factor_shift&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the peak approaches, chlorophyll $a/b$ decays along a Gompertz sigmoid curve while anthocyanin (fiery reds and purples) and carotenoid pigments peak:&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="c1"&gt;# backend/app/services/phenology_model.py:163
# Chlorophyll &amp;amp; Anthocyanin decay curves
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;foliage_pct&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;chlorophyll_pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foliage_pct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;anthocyanin_pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;98.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foliage_pct&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;1.6&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;95.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;chlorophyll_pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;5.0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foliage_pct&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;anthocyanin_pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;20.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;95.0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foliage_pct&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;h3&gt;
  
  
  Architecture Overview
&lt;/h3&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    subgraph Client ["Zero-Screen Client Tier (React 18 + Vite + Tailwind)"]
        UI["Trail Explorer &amp;amp; Peak Timeline (&amp;lt;30s Screen Time)"]
        PrintCard["1-Page Printable Pocket Field Guide"]
        AudioPlayer["Trailhead Audio Player"]
    end

    subgraph BackendGateway ["Backend API (FastAPI on Render)"]
        Router["REST &amp;amp; Hybrid Search Endpoints"]
        CardEngine["Naismith Rule Pocket Card Generator"]
        ElevenLabsService["ElevenLabs Natural Voice Briefing Engine"]
        TabPFNEngine["TabPFN Tabular Regressor Engine"]
        TigerClient["Tiger Data Vector Store Client"]
    end

    subgraph Storage ["Database &amp;amp; Vector Store"]
        TigerDB[("Tiger Data: PostgreSQL + pgvector")]
        TrainingData[("USFS &amp;amp; NOAA Phenology Ground Truth")]
    end

    subgraph DurableOrchestration ["Durable Orchestration (Temporal)"]
        SyncWorkflow["FoliageSyncWorkflow"]
        WeatherAct["fetch_micro_weather_activity"]
        TabPFNAct["batch_tabpfn_inference_activity"]
        DbSyncAct["sync_tiger_db_activity"]
    end

    UI --&amp;gt; Router
    PrintCard --&amp;gt; CardEngine
    AudioPlayer --&amp;gt; ElevenLabsService

    Router --&amp;gt; TabPFNEngine
    Router --&amp;gt; TigerClient
    Router --&amp;gt; ElevenLabsService
    Router --&amp;gt; CardEngine

    TabPFNEngine --&amp;gt; TrainingData
    TigerClient --&amp;gt; TigerDB

    SyncWorkflow --&amp;gt; WeatherAct
    WeatherAct --&amp;gt; TabPFNAct
    TabPFNAct --&amp;gt; TabPFNEngine
    TabPFNAct --&amp;gt; DbSyncAct
    DbSyncAct --&amp;gt; TigerDB&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The stack is &lt;strong&gt;FastAPI, TabPFN, Tiger Data (PostgreSQL + pgvector), Temporal, ElevenLabs, and React 18&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;TabPFN (Prior Labs) Tabular Regressor:&lt;/strong&gt;
Traditional gradient boosted trees (XGBoost/LightGBM) overfit severely on small seasonal datasets without tedious hyperparameter tuning. TabPFN acts as a foundation model for tabular data, running Bayesian neural inference over 11 micro-features (&lt;code&gt;elevation_m&lt;/code&gt;, &lt;code&gt;latitude&lt;/code&gt;, &lt;code&gt;day_of_year&lt;/code&gt;, &lt;code&gt;chill_hours_cumulative&lt;/code&gt;, &lt;code&gt;solar_radiation_mj&lt;/code&gt;, &lt;code&gt;drought_stress_index&lt;/code&gt;, and 5 canopy percentage features) in milliseconds with zero hyperparameter tuning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiger Data (PostgreSQL + &lt;code&gt;pgvector&lt;/code&gt;):&lt;/strong&gt;
Stores trail metadata, elevation profiles, and vector embeddings of forest canopy descriptions. Hikers can run natural language semantic queries (e.g., &lt;em&gt;"golden aspens reflection in high alpine lake"&lt;/em&gt;), combining cosine similarity with relational filters (&lt;code&gt;elevation &amp;gt; 2500m&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporal Durable Workflows:&lt;/strong&gt;
Cold fronts and sudden temperature drops shift foliage timelines overnight. A Temporal &lt;code&gt;FoliageSyncWorkflow&lt;/code&gt; runs background synchronization: polling NOAA weather stations, recomputing TabPFN predictions in batch with automated retry backoffs, and atomically synchronizing updated peak dates to Tiger Data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElevenLabs Audio Briefings:&lt;/strong&gt;
Generates a concise 45-second pre-trail briefing at the trailhead with natural, human cadence (using Brian/Adam nature guide voices) so hikers don't have to read their phones in bright sunlight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1-Page Printable Pocket Card Engine:&lt;/strong&gt;
Uses Naismith's Rule to calculate estimated hiking time based on ascent and distance, laying out key elevation checkpoints and canopy identification notes onto an origami-foldable field sheet.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;This project exists because open science and open-weight tabular AI make decentralized tools viable without relying on closed APIs or corporate walled gardens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verifiable Ecological Physics vs. Black-Box Tourism:&lt;/strong&gt; Closed commercial foliage maps are opaque marketing assets meant to boost hotel bookings. By building on open USFS/NOAA citizen science data and TabPFN, anyone can inspect the biophysical equations governing chill hours and elevation shifts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backcountry Privacy (Zero Telemetry):&lt;/strong&gt; Commercial hiking and fitness trackers routinely upload hiker location history and trails to remote ad trackers. Wander's zero-screen philosophy ensures that your hike stays completely unmonitored: check the model, print the card, and leave no digital footprint on the mountain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Cost Inference Without Token Billing:&lt;/strong&gt; Foundation tabular models like TabPFN run in-memory inference without recurring per-query LLM token costs. Outdoor tools can be hosted affordably by small trail associations and community conservancies.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of TabPFN (Featured):&lt;/strong&gt; TabPFN is the core intelligence engine of Wander, performing tabular regression over 11 bioclimatic features to predict chlorophyll breakdown %, peak color window (72h), and days-to-peak without overfitting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render (Featured):&lt;/strong&gt; Wander's full stack is configured and hosted on Render via Infrastructure-as-Code (&lt;code&gt;render.yaml&lt;/code&gt;), powering the FastAPI Web Service backend and Vite/React Static Site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Tiger Data:&lt;/strong&gt; Uses Tiger Data (PostgreSQL + &lt;code&gt;pgvector&lt;/code&gt;) to index trail geospatial data and run natural language semantic vector search over forest canopy compositions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Temporal:&lt;/strong&gt; Implements a durable &lt;code&gt;FoliageSyncWorkflow&lt;/code&gt; with retry policies to orchestrate periodic micro-weather updates, batch TabPFN model recalculations, and database syncs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs:&lt;/strong&gt; Generates 45-second natural audio pre-trail briefings to deliver key elevation, weather, and species details hands-free at the trailhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Entire:&lt;/strong&gt; The complete interactive agent session documenting the design, implementation, and deployment iterations is embedded directly in this submission.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>tabpfn</category>
      <category>tigerdata</category>
    </item>
    <item>
      <title>I Reverse-Engineered 3 Years of Exam Papers on localhost (With Wi-Fi Off)</title>
      <dc:creator>Aritro Bag</dc:creator>
      <pubDate>Sun, 04 Oct 2026 20:04:12 +0000</pubDate>
      <link>https://dev.to/dev-aarish/i-reverse-engineered-3-years-of-exam-papers-on-localhost-with-wi-fi-off-1p6n</link>
      <guid>https://dev.to/dev-aarish/i-reverse-engineered-3-years-of-exam-papers-on-localhost-with-wi-fi-off-1p6n</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Every AI study tool wants your lecture PDFs. Uploading copyrighted course material to a stranger's inference endpoint is a trade-off, and the friend I built this for wasn't willing to make it.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Gist&lt;/strong&gt;, a study partner that never makes that trade. It runs entirely on the laptop. PDFs are parsed, embedded, and searched locally, the LLM runs locally in Ollama, and the app works with the Wi-Fi switched off. There is no API key in the codebase because there is no API involvement.&lt;/p&gt;

&lt;p&gt;The core of Gist isn't another generic chatbot wrapper. It is an &lt;strong&gt;intelligent past question paper analyser&lt;/strong&gt;. You drop in 3+ years of past university exam PDFs, and Gist reverse-engineers the exam pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which questions and variations repeat.&lt;/li&gt;
&lt;li&gt;What each topic is actually worth in total marks weightage.&lt;/li&gt;
&lt;li&gt;How frequently each concept appears across semesters.&lt;/li&gt;
&lt;li&gt;How your personal quiz drills cross-reference against that weightage.&lt;/li&gt;
&lt;/ol&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%2Fx58a2yqfkntx4q7u9b3m.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%2Fx58a2yqfkntx4q7u9b3m.png" alt="The Past Paper Analyser Workbench and Priority Matrix showing topic weightage breakdowns, past questions, and high-yield weak spots" width="799" height="454"&gt;&lt;/a&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%2Fw7gsnu28ren27z0q6gxm.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%2Fw7gsnu28ren27z0q6gxm.png" alt="Grounded Q&amp;amp;A with direct PDF page citations and Timed Mock Exam drill" width="800" height="455"&gt;&lt;/a&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%2Fskpiz9j41awdb9ytqdl4.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%2Fskpiz9j41awdb9ytqdl4.png" alt="A snapshot from the landing page" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Product page: &lt;a href="https://gist-landing.onrender.com" rel="noopener noreferrer"&gt;https://gist-landing.onrender.com&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Demo Video: &lt;a href="https://youtu.be/QMNTq5FTj8k" rel="noopener noreferrer"&gt;https://youtu.be/QMNTq5FTj8k&lt;/a&gt;&lt;br&gt;
disclaimer: i'm not a good speaker&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/dev-Aarish" rel="noopener noreferrer"&gt;
        dev-Aarish
      &lt;/a&gt; / &lt;a href="https://github.com/dev-Aarish/gist" rel="noopener noreferrer"&gt;
        gist
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Turn your lecture notes and past papers into an offline exam training ground. Grounded RAG with page citations, historical mark weightages, high-yield weak spot detection, and timed mock exams. Runs 100% locally on open-weight LLMs via Ollama — zero cloud, zero API keys.
    &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;Gist&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Gist is an offline, privacy-first AI study partner powered by local open-weight large language models (LLMs) via Ollama, FastAPI, and React. It combines page-grounded document Q&amp;amp;A with an exam intelligence engine that analyzes past question papers, detects topic marks weightages, prioritizes high-yield weak spots, and conducts timed mock exams ("Grill Me" mode).&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Architecture Overview&lt;/h2&gt;
&lt;/div&gt;

  &lt;div class="js-render-enrichment-target"&gt;
    &lt;div class="render-plaintext-hidden"&gt;
      &lt;pre&gt;graph TD
    subgraph UserInterface ["Frontend Client (React 18 + Vite - Dark Theme)"]
        UI["Web Interface: Chat, Past-Paper Workbench, Priority Matrix, Quizzes, Timed Mock Exams"]
    end
    subgraph BackendGateway ["Backend API (FastAPI)"]
        API["REST &amp;amp; SSE Gateway (Port 8000)"]
        Ingest["Document Ingestion Engine (PyMuPDF)"]
        Analyzer["Past-Paper Analyzer Engine"]
        RAG["Grounded RAG Pipeline"]
        Quiz["Adaptive Quiz &amp;amp; Instant Bank Engine"]
        Exam["Mock Exam Simulator ('Grill Me' Engine)"]
    end
    subgraph StorageLayer ["Local Persistent Storage"]
        Chroma["ChromaDB: Vector Embeddings"]
        SQLite["SQLite (tracker.db): Papers, Question Bank, Mastery &amp;amp; Attempt History"]
        Uploads["PDF Storage (data/uploads)"]
    end

    subgraph LocalLLM ["Local Inference Engine (Ollama)"]
        EmbedModel["Embedding Models: nomic-embed-text / bge-m3"]
        ChatModel["Dynamic Open-Weight Models: Gemma&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dev-Aarish/gist" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The parsing rules are the part I'd walk through first. Marks appear in university papers as &lt;code&gt;[10]&lt;/code&gt;, &lt;code&gt;(5 marks)&lt;/code&gt;, &lt;code&gt;15M&lt;/code&gt;, or a bare &lt;code&gt;4 + 6 + 2 = 12&lt;/code&gt; breakdown, and getting this wrong means every downstream percentage is wrong:&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="c1"&gt;# backend/analyzer.py:134
&lt;/span&gt;&lt;span class="n"&gt;m_single&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;(?:\[|\()?\b(\d{1,2})\s*(?:marks?|mark|m|pts?)\b(?:\]|\))?|\[(\d{1,2})\]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Mark weightage is the input to the entire priority model, so it has to come out of the PDF exactly, not approximately.&lt;/p&gt;
&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Everything runs on the user's machine. No network calls leave the host, which makes the privacy claim checkable rather than a policy promise.&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%2Flqrf2vcjzf0ddfuyleqk.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%2Flqrf2vcjzf0ddfuyleqk.png" alt="Architecture diagram showing every component inside a single box representing the user's machine: a React 18 and Vite client calls a local FastAPI server over localhost, which dispatches to four engines (PyMuPDF ingestion, the past-paper analyser, grounded RAG, and a mock exam grader). These read and write ChromaDB for vector search, SQLite at data/tracker.db for papers and mastery, and the original PDFs in data/uploads. All four engines call a local Ollama runtime on port 11434. No connection leaves the box." width="799" height="424"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Pipeline
&lt;/h3&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%2Frpyplnfr8jkhf4q03e1k.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%2Frpyplnfr8jkhf4q03e1k.png" alt="Flowchart of the past-paper analyser. A PDF passes through a regex metadata scan for year, total marks, and title, then a decision on whether question boundaries were found by regex. If yes, questions are split on patterns like Q1(a), 2., and (i) with marks extracted per line, topics are inferred by keyword so terms like bcnf and 3nf map to Normalization, and a second decision sends only still-unclassified questions to a micro-LLM pass capped at 12 questions and 200 tokens. If no boundaries were found, full LLM extraction is the fallback. Both paths fold results onto a canonical topic map, write questions, marks, and topics to SQLite, and feed a priority matrix computed as marks percentage times weakness, producing a ranked revision list. A dotted background thread also indexes the paper into ChromaDB." width="645" height="1717"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The stack is FastAPI, PyMuPDF, ChromaDB, SQLite, and Ollama on the backend, React on the front. About 4,700 lines of Python now, up from 2,000 when the quiz was the main feature.&lt;/p&gt;
&lt;h4&gt;
  
  
  Resources I took help of:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Antigravity(CLI)&lt;/li&gt;
&lt;li&gt;Opencode&lt;/li&gt;
&lt;li&gt;Freebuff&lt;/li&gt;
&lt;li&gt;Skills(frontend-design, ui-ux-pro-max, emil-design-eng, impeccable, documentation-writer)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Why the Analyser is Rules-First, LLM-Second
&lt;/h3&gt;

&lt;p&gt;My first prototype sent the entire exam paper to an LLM asking for structured JSON. It was sluggish, expensive on local compute, and hallucinated marks.&lt;/p&gt;

&lt;p&gt;The current architecture is a &lt;strong&gt;three-stage hybrid pipeline&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic Regex Parse&lt;/strong&gt;: Splits questions on structural boundaries (&lt;code&gt;Q1(a)&lt;/code&gt;, &lt;code&gt;2.&lt;/code&gt;, &lt;code&gt;(i)&lt;/code&gt;), groups MCQ sub-options under their parents, filters boilerplate university headers, and extracts marks per line. Runs in milliseconds with 100% fidelity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyword Topic Inference&lt;/strong&gt;: A domain-specific ontology maps question vocabulary to canonical syllabus topics (&lt;code&gt;bcnf&lt;/code&gt;, &lt;code&gt;3nf&lt;/code&gt;, &lt;code&gt;attribute closure&lt;/code&gt; → &lt;em&gt;Normalization&lt;/em&gt;; &lt;code&gt;precedence graph&lt;/code&gt;, &lt;code&gt;2pl&lt;/code&gt;, &lt;code&gt;dirty read&lt;/code&gt; → &lt;em&gt;Transactions&lt;/em&gt;). Using deterministic mapping prevents small 7B models from inventing arbitrary topic names.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micro-LLM Pass for Edge Cases&lt;/strong&gt;: Only unclassified questions falling through to the generic category are sent to Ollama, batched at ≤ 12 snippets with &lt;code&gt;num_predict=200&lt;/code&gt;. Full LLM extraction is reserved strictly as a fallback for unstructured, legacy scanned layouts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A canonical topic dictionary folds all variations back into fixed buckets so percentages aggregate cleanly without fragmentation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Turning Weightage into a Ranked Study Plan
&lt;/h3&gt;

&lt;p&gt;Two mathematical formulas drive the recommendation engine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Exam Importance&lt;/strong&gt; measures how heavily a topic features across years, with frequency acting as a credibility multiplier on total marks share:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;exam_importance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;marks_pct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frequency_pct&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;(Multiplication ensures a topic worth 15% across all past papers ranks significantly higher than a topic appearing in only one isolated year).&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Composite Priority&lt;/strong&gt; scales exam weight against your personal weakness:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exam_importance&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;accuracy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Open Innovation Matters
&lt;/h2&gt;

&lt;p&gt;This project exists solely because open weights and local runtimes are now viable on standard consumer laptops. A closed, cloud-only model would have compromised the project in three fundamental ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verifiable Privacy&lt;/strong&gt;: No keys to leak, no remote database to breach, and no data harvesting. Anyone can audit the 4,700 lines of Python and verify that zero packets leave &lt;code&gt;localhost&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Cost Feedback Loops&lt;/strong&gt;: Prompt tuning and evaluation loops take seconds. Tweaking extraction prompts and re-running against local weights is free, reproducible, and immune to upstream provider deprecations or rate limits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid Architecture Viability&lt;/strong&gt;: A deterministic rules-first pipeline that saves LLM calls only makes architectural sense when local execution is unmetered.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;Here is the interactive session trace detailing the design iterations behind the local-first architecture, the 3-stage hybrid parsing engine, and the priority formula:&lt;/p&gt;


&lt;div class="ltag-agent-session"&gt;
  &lt;div class="agent-session-header"&gt;
    
    &lt;span class="agent-session-tool-icon-badge" title="Gemini CLI"&gt;
&lt;/span&gt;
    &lt;span class="agent-session-title"&gt;Building Gist: Local-First Offline Exam Intelligence &amp;amp; 3-Stage Hybrid Parser&lt;/span&gt;
  &lt;/div&gt;

  &lt;div class="agent-session-scroll"&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;How can we build Gist as a 100% local, offline exam intelligence engine so that no university course PDFs ever leave the student's laptop?&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;We design an entirely local architecture powered by Ollama for local open-weight LLMs (Gemma 2 / Llama 3.2), FastAPI for the backend gateway, PyMuPDF for deterministic extraction, ChromaDB for local vector search, and SQLite for persistent tracking. Zero API keys, zero network telemetry.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-runcommand"&gt;run_command&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;cat &amp;lt;&amp;lt; 'EOF' &amp;gt; backend/architecture_spec.md
# Local-First Architecture:
1. Do...&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ cat &amp;lt;&amp;lt; 'EOF' &amp;gt; backend/architecture_spec.md
# Local-First Architecture:
1. Document Ingestion: PyMuPDF (Local)
2. Vector Indexing: ChromaDB (Local SQLite/DuckDB)
3. Topic Classifier: Regex heuristics + Keyword Ontology + Ollama fallback
4. Storage: SQLite tracker.db
EOF&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;Architecture spec initialized.&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;The LLM is hallucinating marks and taking too long when parsing entire exam PDFs at once. How do we make question and marks extraction deterministic and fast?&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;We replace full-paper LLM generation with a 3-Stage Hybrid Parser:&lt;br&gt;
1. Deterministic Regex Parsing: Extract question boundaries (e.g. Q1(a), 2.) and mark tags ([10], (5 marks), 15M) in milliseconds with 100% fidelity.&lt;br&gt;
2. Keyword Ontology Inference: Map question keywords directly to syllabus topics (e.g. 'bcnf', '3nf' -&amp;gt; Normalization).&lt;br&gt;
3. Micro-LLM Pass: Only send leftover, unclassified questions to Ollama in small batches with low token limits.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-writetofile"&gt;write_to_file&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;# backend/analyzer.py regex pattern matching
m_single = re.search(r'(?:\[|\()...&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;# backend/analyzer.py regex pattern matching
m_single = re.search(r'(?:\[|\()?\b(\d{1,2})\s*(?:marks?|mark|m|pts?)\b(?:\]|\))?|\[(\d{1,2})\]', line, re.I)&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;Updated backend/analyzer.py with deterministic parsing rules.&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;How do we turn the extracted topic mark weightage and student quiz accuracy into an actionable revision priority matrix?&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;We compute Exam Importance using question frequency as an amplifier over marks share, then multiply by student weakness:&lt;br&gt;
- exam_importance = marks_pct * (0.6 + 0.4 * (frequency_pct / 100))&lt;br&gt;
- priority = exam_importance * ((100 - accuracy) / 100) * 1.5&lt;br&gt;
Untested topics are penalized with an assumed 75% weakness rather than 0% accuracy to prioritize high-risk unknowns safely.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class="agent-session-footer"&gt;
    &lt;span class="agent-session-meta"&gt;
        6 of 6 messages
    &lt;/span&gt;
  &lt;/div&gt;
&lt;/div&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;: Gist is built on Google's open-weight &lt;strong&gt;Gemma 2&lt;/strong&gt; (&lt;code&gt;gemma2:9b&lt;/code&gt; and lightweight &lt;code&gt;gemma2:2b&lt;/code&gt;), running locally via Ollama to power the micro-LLM topic classification pass, grounded RAG answering, and automated mock exam grading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt;: The interactive product landing page and live web preview are deployed on &lt;strong&gt;Render&lt;/strong&gt; at &lt;a href="https://gist-landing.onrender.com" rel="noopener noreferrer"&gt;https://gist-landing.onrender.com&lt;/a&gt; (configured via &lt;code&gt;render.yaml&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Entire&lt;/strong&gt;: The agent session transcript behind Gist's local-first architecture and hybrid parser design is embedded directly in this write-up.&lt;/li&gt;
&lt;/ul&gt;

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