<?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: Yuvan Shankar M</title>
    <description>The latest articles on DEV Community by Yuvan Shankar M (@yuvan_shankar).</description>
    <link>https://dev.to/yuvan_shankar</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%2F4175117%2F6624282a-651d-4d77-96cc-bcd56008696a.png</url>
      <title>DEV Community: Yuvan Shankar M</title>
      <link>https://dev.to/yuvan_shankar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yuvan_shankar"/>
    <language>en</language>
    <item>
      <title>I built a $0 alternative to $300/hr legal tech (and survived 190s API hangs doing it)</title>
      <dc:creator>Yuvan Shankar M</dc:creator>
      <pubDate>Sat, 17 Oct 2026 15:39:01 +0000</pubDate>
      <link>https://dev.to/yuvan_shankar/i-built-a-0-alternative-to-300hr-legal-tech-and-survived-190s-api-hangs-doing-it-1n8e</link>
      <guid>https://dev.to/yuvan_shankar/i-built-a-0-alternative-to-300hr-legal-tech-and-survived-190s-api-hangs-doing-it-1n8e</guid>
      <description>&lt;p&gt;&lt;strong&gt;What I Built&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Legal tech has an awkward habit: it asks you to upload your most sensitive documents to a black box, charges you $300 an hour, or spits out a ten-page generic summary that still requires a law degree to understand.&lt;br&gt;
The Private Contract &amp;amp; Lease Decoder solves this. It’s a free, blazing-fast tool that acts as a first-pass legal reviewer. You paste a contract (or upload a PDF/DOCX), select your role (e.g., Freelancer, Tenant), and in just 2-3 seconds, it gives you:&lt;br&gt;
A bulleted list of specific red flags, hidden traps, and unfair clauses.&lt;br&gt;
A polite, professional draft email to negotiate those exact terms.&lt;br&gt;
A 1–10 "predatory risk" score.&lt;br&gt;
An audio read-out of the negotiation email so you can listen to it on the go.&lt;br&gt;
It’s built for anyone who needs to verify a document before signing but can’t afford a lawyer: a student signing their first freelance gig, a tenant reviewing a new lease, or a small business owner checking a vendor agreement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Live App: &lt;a href="https://private-contract-decoder.onrender.com" rel="noopener noreferrer"&gt;https://private-contract-decoder.onrender.com&lt;/a&gt;&lt;br&gt;
(Note: Because it runs on Render’s free tier, the very first click after a long idle period takes ~5 seconds to wake the server. Every click after that is instant thanks to in-memory caching.)&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%2F6ore0i9dm02reqtci13o.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%2F6ore0i9dm02reqtci13o.png" alt="UI 1" width="800" height="406"&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%2Fs5n0bheelqcqup7kk9xk.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%2Fs5n0bheelqcqup7kk9xk.png" alt="UI 2" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;/p&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/yuvanshankarm007" rel="noopener noreferrer"&gt;
        yuvanshankarm007
      &lt;/a&gt; / &lt;a href="https://github.com/yuvanshankarm007/private-contract-decoder" rel="noopener noreferrer"&gt;
        private-contract-decoder
      &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;🛡️ Private Contract &amp;amp; Lease Decoder&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A fast, private, and free AI tool that acts as a first-pass legal reviewer. Upload a contract or lease, and in seconds, get a bulleted list of red flags, a professional negotiation email, and a predatory risk score.&lt;/p&gt;
&lt;p&gt;Built for students, freelancers, and tenants who need to verify documents before signing but can't afford a $300/hr lawyer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; [Insert Your Render URL Here]&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parallel AI Analysis:&lt;/strong&gt; Three AI routers fire simultaneously to analyze the document in ~3 seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-Healing Fallback Chains:&lt;/strong&gt; If a model fails, times out, or gets deprecated, the app instantly hops to the next available model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Format Support:&lt;/strong&gt; Upload PDFs, DOCX files, or paste raw text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio Read-Out:&lt;/strong&gt; Listen to your negotiation email on the go via ElevenLabs (with a silent fallback to free gTTS).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100% Private:&lt;/strong&gt; No data is stored. The app processes text in memory and…&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/yuvanshankarm007/private-contract-decoder" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;How I Built It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The architecture is conceptually simple, but making it fast, resilient, and reliable on free-tier APIs was the real engineering challenge. I built a parallel, self-healing router system with hard timeouts using Python's ThreadPoolExecutor.&lt;br&gt;
Instead of running sequentially (which would easily take 15+ seconds), three AI routers fire at the exact same time:&lt;br&gt;
Router 1 (Deep Analysis): Uses larger open-weight models to find specific legal red flags and hidden fees.&lt;br&gt;
Router 2 (Email Drafting): Uses fast, structured models to draft a polite, professional negotiation email.&lt;br&gt;
Router 3 (Risk Scoring): Uses a lightweight model with strict regex parsing to output a 1-10 predatory risk score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observability: How Sentry Saved the Build&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My first version took a staggering 190 seconds to return a result. I was completely blind to why until I wrapped the main pipeline in a @sentry_sdk.trace decorator.&lt;br&gt;
The Sentry Performance dashboard let me visually see the three router spans firing in parallel, and more importantly, it flagged the exact bottleneck: silent API errors causing a retry loop with no timeout, hanging for ~13 seconds per attempt.&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%2Fb55qt6f522auecnzbkdk.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%2Fb55qt6f522auecnzbkdk.png" alt="Sentry" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sentry caught every critical error during development, from the 190s timeout hangs to the deprecated model calls, letting me fix them before the demo.&lt;br&gt;
Once I saw the traces, I added hard 10-second timeouts to every client and strict token budgets. If a model hangs or throws a gateway error, the router instantly kills the connection and hops to the next one. That single fix, guided entirely by Sentry, dropped my p95 latency from 190 seconds down to 6-8 seconds(due to audio rendering).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Surviving Mid-Hackathon API Nightmares&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building on free-tier APIs means dealing with constant, unpredictable changes. During this build alone, I faced three major hurdles that would have broken a naive app:&lt;br&gt;
The Decommissioned Model: Mid-build, Groq quietly deprecated an older Llama model I was relying on. A closed system relying on a single hardcoded model would have just crashed. Because I built a fallback chain, the router simply caught the 400 model_decommissioned error, hopped to the next model in the list, and kept going without the user ever noticing.&lt;br&gt;
The Namespace Shift: Groq suddenly changed their API naming convention, requiring prefixes like openai/ for their new GPT-OSS models. This caused a wave of 404 model_not_found errors. I had to quickly pivot, use the Groq Playground to identify the new live IDs, and update my fallback chains dynamically.&lt;br&gt;
The "Lazy" Model: Router 2 kept cutting off the email draft abruptly after the subject line. I realized the model was getting overwhelmed by long contracts. I fixed it by truncating the context window to the first 600 characters and switching the drafting router to Qwen, which excels at structured writing tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching and Audio Resilience&lt;/strong&gt;&lt;br&gt;
To make the app feel truly production-ready, I added a simple dictionary-based response cache keyed to the hash of the input text. If a user analyzes the same contract twice, the second request bypasses the AI entirely and returns in 0.1 seconds.&lt;br&gt;
For the audio, the email is read aloud via ElevenLabs. But free-tier credits run out fast. I wrote a silent failover: if the ElevenLabs API throws an error, the app instantly catches it and switches to the free gTTS library, ensuring the demo never breaks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Does Open Innovation Matter?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It costs nothing to run, so it can stay free. A fallback chain of open-weight models routed through flexible providers means I’m not locked into a single vendor’s pricing, rate limits, or sudden policy changes.&lt;br&gt;
I could see and steer every step. When a model failed, I could inspect the raw Sentry error, see exactly which model name was deprecated, and update the chain. Open weights let me understand why it failed, not just that it failed.&lt;br&gt;
Resilience is a feature. Free tiers get throttled. Open innovation made it possible to build a self-healing app on a $0 budget, rather than a fragile demo that breaks the moment a closed, proprietary API has a bad day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Agent Session&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note: This project was built using custom Python orchestration and parallel routing rather than a heavy, multi-step agent framework. I prioritized a deterministic, self-healing agent harness to ensure speed and predictability, avoiding the complex reasoning loops that would easily blow past free-tier timeouts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My First User&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I had a friend who needed to verify a freelance contract before signing it. He uploaded the document to the app, and it immediately flagged a few unfair clauses and hidden fees he had completely missed. It gave him a clear, plain-English breakdown of the risks, which he used to ask the client for a quick revision before signing. It was a small win, but it proved the tool does exactly what it's supposed to: catch the fine print before it becomes a problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lessons Learned&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Never ship an API call without a hard timeout. The 190-second hang taught me that the hard way. Optimism is not a concurrency strategy.&lt;br&gt;
Model names rot weekly. Build fallback chains from day one. Hardcoding a single model ID is a ticking time bomb.&lt;br&gt;
Parallel execution is free speed. Three routers firing concurrently via ThreadPoolExecutor is exactly why this feels instant to the end user.&lt;br&gt;
Observability is non-negotiable. Without Sentry's distributed tracing, I would have been blindly guessing why the app was hanging for 3 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prize Categories-&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Best Use of Sentry: Distributed tracing of the parallel router fan-out, which was instrumental in diagnosing the 190-second timeout bug and catching live API errors.&lt;br&gt;
Best Use of Render: $0 hosting with a startup warm-up thread and environment-variable secrets.&lt;br&gt;
Best Use of ElevenLabs: Voice generation with a graceful, silent degradation to free gTTS if credits run out.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Touch Grass Garden: a plant tracker that only counts the days you went outside</title>
      <dc:creator>Yuvan Shankar M</dc:creator>
      <pubDate>Mon, 12 Oct 2026 03:35:42 +0000</pubDate>
      <link>https://dev.to/yuvan_shankar/touch-grass-garden-a-plant-tracker-that-only-counts-the-days-you-went-outside-10na</link>
      <guid>https://dev.to/yuvan_shankar/touch-grass-garden-a-plant-tracker-that-only-counts-the-days-you-went-outside-10na</guid>
      <description>&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Most apps want you to open them every day. I wanted to build one that doesn't care whether you open it at all.&lt;/p&gt;

&lt;p&gt;Touch Grass Garden is a plant tracker for beginners. You enter your location and what you sowed, and it works out the season and suggests what to plant this month. Every day it writes a short card with the best time to go out, any weather warnings, and one thing to look for at each plant. After that you close the laptop and go and look at the real plant.&lt;/p&gt;

&lt;p&gt;The streak is the part I care about most. It only counts days when you log a check-in at your plants, and opening the app earns nothing. The weekly goal, the badges and the 12-week heatmap all use the same rule, so the only way to make progress is to go outside.&lt;/p&gt;

&lt;p&gt;Here's everything it does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It reads your coordinates and the date to find the season (kharif, rabi or zaid in India, four seasons elsewhere), then lists what's good to sow this month with the growing method and what each crop needs (sun, water, soil).&lt;/li&gt;
&lt;li&gt;Each plant gets stages like sown, germinated, flowering and harvest, with expected dates worked out from the sowing date.&lt;/li&gt;
&lt;li&gt;Every day Gemma writes a short outdoor card: the best time to go out, weather alerts, and one thing to look for at each plant.&lt;/li&gt;
&lt;li&gt;For check-ins you pick the stage you actually see, add a note, tick if you watered, and attach a photo. Each plant has a timeline with a chart and the photos.&lt;/li&gt;
&lt;li&gt;Watering reminders are based on how often each crop needs water, with a warning when heavy rain is forecast.&lt;/li&gt;
&lt;li&gt;The streak, a weekly target (4 days by default), badges and a 12-week calendar heatmap all come from real check-ins only.&lt;/li&gt;
&lt;li&gt;The garden recap shows days outside, longest streak and totals for each plant, with a download button.&lt;/li&gt;
&lt;li&gt;The printable card is a plain-text card with tick boxes and "what I saw" lines, so you can take it outside without a screen.&lt;/li&gt;
&lt;li&gt;Each crop has two "if you see this" tips for common problems and what to do about each.&lt;/li&gt;
&lt;li&gt;Anyone can drop a JSON file into a folder to add or change crops for their own region (I call these crop packs).&lt;/li&gt;
&lt;li&gt;Deleting a plant or a check-in asks for confirmation first.&lt;/li&gt;
&lt;li&gt;I also added two experimental extras. The card can be written in a few other languages (Hindi, Tamil and others), and the local model can describe a check-in photo. I haven't tested either properly, so I don't know how good the output is. The photo description is labelled as an unverified AI description in the app.&lt;/li&gt;
&lt;li&gt;Weather alerts use each crop's own temperature limits, so a cold night warns about the plants it would actually hurt. Plants of the same crop are grouped into one alert, and the heat threshold is stricter so it doesn't warn all the time.&lt;/li&gt;
&lt;li&gt;Saved photos are resized to 1600 px at most and stripped of EXIF location data, and the log is saved atomically so a crash can't corrupt it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  I Took It Outside
&lt;/h2&gt;

&lt;p&gt;It was a good morning for it, and I could hear birds the whole time. I had planted a tomato and a chilli next to my hibiscus plant, so I took the card out there.&lt;/p&gt;

&lt;p&gt;This is what it said:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for moist, not waterlogged soil around the Tomato plants.&lt;/li&gt;
&lt;li&gt;Examine the timmy for moist, not waterlogged soil.&lt;/li&gt;
&lt;li&gt;Observe the soil conditions for both plants during the best time.&lt;/li&gt;
&lt;li&gt;Put the phone away and truly look at your plants.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The soil was moist because it had rained the day before, but it wasn't waterlogged. The ground had soaked up the extra water. The card got the one useful thing right, which was to check soil moisture. It had no idea it had rained, so that was partly luck. The rest wasn't great: three of the four bullets say almost the same thing, and "Examine the timmy"(The card calls my chilli "timmy" because that's the nickname I gave it.) is just clumsy. A 4B model does that. With wifi off, the first card took about 30 seconds because the model had to load. After that, each card took about 6 seconds, online or offline.&lt;/p&gt;

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

&lt;p&gt;The app runs on my laptop, so there's no live link. Here's a walkthrough:&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiqgvs2objq4pb7lgprj2.jpeg" 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%2Fiqgvs2objq4pb7lgprj2.jpeg" alt="Where I planted" width="800" height="600"&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%2Fxir3vs5frs14x3yhht1m.jpeg" 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%2Fxir3vs5frs14x3yhht1m.jpeg" alt="My hibiscus plant" width="800" height="1067"&gt;&lt;/a&gt;&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/yuvanshankarm007" rel="noopener noreferrer"&gt;
        yuvanshankarm007
      &lt;/a&gt; / &lt;a href="https://github.com/yuvanshankarm007/touch-grass-garden" rel="noopener noreferrer"&gt;
        touch-grass-garden
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A plant tracker that rewards you for going outside, not for opening the app. Local AI (Gemma via Ollama), works offline.
    &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;Touch Grass Garden (v3.0)&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A plant milestone tracker that rewards you for going &lt;strong&gt;outside&lt;/strong&gt;, not for opening the app.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detects the local season from your coordinates and the date&lt;/li&gt;
&lt;li&gt;Suggests what to sow this month, with the growing method and requirements for each crop&lt;/li&gt;
&lt;li&gt;Tracks each plant through growth milestones (sown -&amp;gt; germinated -&amp;gt; ... -&amp;gt; harvest)&lt;/li&gt;
&lt;li&gt;Builds a short "today's outdoor card" with a local open-weight model (Gemma via Ollama)&lt;/li&gt;
&lt;li&gt;Weather alerts and a best-time-outside window (rule-based, forecast cached for offline use)&lt;/li&gt;
&lt;li&gt;The streak counts &lt;strong&gt;days you logged a check-in at your plants&lt;/strong&gt; - opening the app earns nothing&lt;/li&gt;
&lt;li&gt;Weekly outdoor goal (default 4 days) with a progress bar - only real check-ins count&lt;/li&gt;
&lt;li&gt;Photo log: attach a photo to each outdoor check-in and see it in the plant's timeline&lt;/li&gt;
&lt;li&gt;Growth timeline: chart and history of every check-in per plant&lt;/li&gt;
&lt;li&gt;Care reminders: watering due dates from &lt;code&gt;crops.json&lt;/code&gt;…&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/yuvanshankarm007/touch-grass-garden" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;To run it, install Ollama, run &lt;code&gt;ollama pull gemma3:4b&lt;/code&gt;, then &lt;code&gt;pip install -r requirements.txt&lt;/code&gt; and &lt;code&gt;streamlit run app.py&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;I used Gemma 3 (4B) through Ollama, so everything runs on my own laptop. The app is Python and Streamlit. The logic lives in one file and the UI in another, and plants and check-ins are stored in a plain JSON file.&lt;/p&gt;

&lt;p&gt;A few choices I made:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All the crop info lives in one &lt;code&gt;crops.json&lt;/code&gt; file, and the model is only allowed to use what I hand it. I didn't want a small model inventing planting advice.&lt;/li&gt;
&lt;li&gt;The season comes from a simple lookup on location and date, with the Indian calendar (kharif, rabi, zaid) inside India and four seasons elsewhere.&lt;/li&gt;
&lt;li&gt;The forecast comes from Open-Meteo and gets saved to a file, so the app still has the last forecast when it's offline and shows how old it is. The alerts and the "best time outside" window are plain rules. The window is the longest stretch of daylight hours that are cool enough, dry enough and not too windy. The model never decides an alert, it only words things.&lt;/li&gt;
&lt;li&gt;For the prompt, I told the model to output only the card, use each plant's exact name, combine advice that repeats across plants, keep it under about 70 words, never mention watering unless it's due, and end by telling you to put the phone away.&lt;/li&gt;
&lt;li&gt;If Ollama isn't running, the app shows a rule-based card instead, so it never breaks in the garden.&lt;/li&gt;
&lt;li&gt;Unit tests cover seasons, streaks, the weekly goal, alerts, watering, the timeline, crop packs and the fallback card. There's also a smoke test that loads the whole app without opening a browser. GitHub Actions runs all of it on every push, on Python 3.11 and 3.12, with a Ruff lint check and a check that every crop pack loads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first version of the card told me to water a plant that wasn't due for two days. I had passed in "next watering in about 2 days" and the model took it as an instruction. With two plants it also repeated the same bullet. I fixed it by only sending watering info when it's actually due, and by telling the model not to repeat itself. Even then it looked broken for a while, because my Generate button was showing a cached card. The card is still a bit repetitive, as you can see above, but the bigger lesson was that a small model does better with less context and stricter rules.&lt;/p&gt;

&lt;p&gt;I built most of the app with Claude and used GitHub's Copilot coding agent for some follow-up features. The voiceover in the demo is from ElevenLabs.&lt;/p&gt;

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

&lt;p&gt;A planting guide is most useful in a garden or on a farm, and those are the places with the worst signal. An app that needs a connection to work is a bad fit.&lt;/p&gt;

&lt;p&gt;Running Gemma locally fixes that. The advice, the milestones and the daily card all work on the laptop. Only the forecast needs internet, and the last one is saved, so it's mostly offline rather than fully offline.&lt;/p&gt;

&lt;p&gt;A few other things it made possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your location and plant notes never leave your device. With a hosted API, all of it would go to a server I don't control.&lt;/li&gt;
&lt;li&gt;Nothing is charged per request, which matters for something meant for people growing food on a budget.&lt;/li&gt;
&lt;li&gt;I can swap in a smaller model on a weaker machine, and I can change how it behaves just by editing the prompt.&lt;/li&gt;
&lt;li&gt;Crop packs are just JSON files, so someone who actually grows things in their region can fix my data without touching any code. I'd want that, because my crop data is a starter set and no expert has checked it. The README tells people to confirm it locally.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The limits: a 4B model makes mistakes, which is why alerts are rules and not model output. I've also only tested the app for two days, so I can't show real growth over time yet.&lt;/p&gt;

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

&lt;p&gt;I didn't record a DevRelay session. The Copilot agent's work is public on GitHub, so here are the issues and pull requests it worked on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Issues: #1, #3, #5, #7, #9, #11&lt;/li&gt;
&lt;li&gt;Pull requests: #2, #4, #6, #8, #10, #12&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Best Use of Gemma: the daily card is written by &lt;code&gt;gemma3:4b&lt;/code&gt; running locally through Ollama.&lt;/li&gt;
&lt;li&gt;Best Use of GitHub Copilot: I wrote &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; with the project's rules (logic in &lt;code&gt;garden.py&lt;/code&gt; with no UI code, alerts are rules and never the model, crop facts only from &lt;code&gt;crops.json&lt;/code&gt;, a test for every change). Then I gave the coding agent six real issues and reviewed every pull request before merging. It built the crop-specific temperature alerts (&lt;a href="https://github.com/yuvanshankarm007/touch-grass-garden/pull/2" rel="noopener noreferrer"&gt;#2&lt;/a&gt;), atomic saves and privacy-safe photos (&lt;a href="https://github.com/yuvanshankarm007/touch-grass-garden/pull/4" rel="noopener noreferrer"&gt;#4&lt;/a&gt;), plant and check-in deletion (&lt;a href="https://github.com/yuvanshankarm007/touch-grass-garden/pull/6" rel="noopener noreferrer"&gt;#6&lt;/a&gt;), quieter weather alerts (&lt;a href="https://github.com/yuvanshankarm007/touch-grass-garden/pull/8" rel="noopener noreferrer"&gt;#8&lt;/a&gt;), the calendar heatmap (&lt;a href="https://github.com/yuvanshankarm007/touch-grass-garden/pull/10" rel="noopener noreferrer"&gt;#10&lt;/a&gt;) and a stronger CI workflow (&lt;a href="https://github.com/yuvanshankarm007/touch-grass-garden/pull/12" rel="noopener noreferrer"&gt;#12&lt;/a&gt;). All six are merged. CI runs on GitHub Actions on every push. On #8 I left review feedback, but the agent ran out of monthly credits before it could act on it, so I merged it as it was.&lt;/li&gt;
&lt;li&gt;Best Use of ElevenLabs: the narration in my demo video was generated with ElevenLabs text-to-speech using the Eleven v4 model and the "Dev Shah - Smooth and Engaging" voice. Here's the script and the generation I used:&lt;/li&gt;
&lt;/ul&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%2F6bi65khc858zp8yp5ro6.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%2F6bi65khc858zp8yp5ro6.png" alt=" " width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm a solo participant.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>hacktoberfest</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I’m a first-year CS student building a free, open-source Descript alternative</title>
      <dc:creator>Yuvan Shankar M</dc:creator>
      <pubDate>Sun, 11 Oct 2026 06:25:26 +0000</pubDate>
      <link>https://dev.to/yuvan_shankar/im-a-first-year-cs-student-building-a-free-open-source-descript-alternative-662</link>
      <guid>https://dev.to/yuvan_shankar/im-a-first-year-cs-student-building-a-free-open-source-descript-alternative-662</guid>
      <description>&lt;p&gt;Hi DEV! I'm a first-year computer science student, and I'm excited to finally join the community.&lt;/p&gt;

&lt;p&gt;I'm interested in AI, software development and open source. Right now I'm working on a small project to make video editing easier using AI, and learning a lot along the way. I'll share what I build and what I learn here.&lt;/p&gt;

&lt;p&gt;I'd love to connect with other developers and learn from you. What's one thing you wish you'd known when you were starting out?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>python</category>
    </item>
  </channel>
</rss>
