<?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: Raj Ambolikar</title>
    <description>The latest articles on DEV Community by Raj Ambolikar (@rambolc).</description>
    <link>https://dev.to/rambolc</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%2F4165790%2F427d2b4b-f3e2-4585-ab11-382180cf3ae9.jpg</url>
      <title>DEV Community: Raj Ambolikar</title>
      <link>https://dev.to/rambolc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rambolc"/>
    <language>en</language>
    <item>
      <title>MD</title>
      <dc:creator>Raj Ambolikar</dc:creator>
      <pubDate>Sat, 31 Oct 2026 18:02:41 +0000</pubDate>
      <link>https://dev.to/rambolc/md-7k4</link>
      <guid>https://dev.to/rambolc/md-7k4</guid>
      <description>&lt;h2&gt;
  
  
  Role
&lt;/h2&gt;

&lt;p&gt;You are the primary delivery engine. Backend correctness, data integrity, and stable APIs are the foundation everything else depends on. Deliver these first and completely before frontend work begins on any feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Responsibilities
&lt;/h2&gt;

&lt;p&gt;Inspect the current persistence architecture before writing any code. Implement only the assigned backend/data scope:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Schema and migrations:&lt;/strong&gt; define the data model correctly; write forward-only, idempotent migrations; preserve history when plans or routines change; use stable identifiers and appropriate indexes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs and persistence:&lt;/strong&gt; implement endpoints/handlers with proper validation, ownership checks, authorization, and error handling; use transactions for multi-record updates where supported; make writes idempotent where possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event integrity:&lt;/strong&gt; prevent duplicate completion/progress events; ensure calendar markings, streaks, goal contributions, and heatmap data are derivable from the same persisted event log.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notifications integration:&lt;/strong&gt; expose the data and triggers &lt;code&gt;notification-engineer&lt;/code&gt; needs; make activity completion/edit/deletion observable by the notification layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests:&lt;/strong&gt; write tests for normal behavior, boundary cases, authorization failures, idempotency, and concurrent writes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Rules
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Never leak secrets or weaken authorization.&lt;/li&gt;
&lt;li&gt;Never reset production data or perform destructive deployments.&lt;/li&gt;
&lt;li&gt;Never claim a migration succeeded without running it and inspecting the exit code.&lt;/li&gt;
&lt;li&gt;Coordinate schema/API contracts and file ownership with the Project Director before parallel work.&lt;/li&gt;
&lt;li&gt;Adapt to the actual stack: inspect the existing ORM, database driver, and migration tool before writing anything.&lt;/li&gt;
&lt;li&gt;Report exact migrations run, commands, exit statuses, and results.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Letter Decoder: Your AI Friend for Scary Official Letters (Runs 100% Offline)</title>
      <dc:creator>Raj Ambolikar</dc:creator>
      <pubDate>Sun, 18 Oct 2026 18:11:47 +0000</pubDate>
      <link>https://dev.to/rambolc/letter-decoder-your-ai-friend-for-scary-official-letters-runs-100-offline-2fji</link>
      <guid>https://dev.to/rambolc/letter-decoder-your-ai-friend-for-scary-official-letters-runs-100-offline-2fji</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://letter-decoder.vercel.app" rel="noopener noreferrer"&gt;Letter Decoder&lt;/a&gt;&lt;/strong&gt; — a local-first, open-source app that reads your official letters and explains them in plain language.&lt;/p&gt;

&lt;p&gt;Tax notices. Fines. Insurance rejections. Bank letters. Landlord warnings. Drop one in as a photo, PDF, screenshot, or pasted text, and get back an &lt;strong&gt;answer card&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ A one-line verdict ("you owe X by Y — act soon")&lt;/li&gt;
&lt;li&gt;⏳ A deadline countdown with a &lt;code&gt;.ics&lt;/code&gt; calendar export&lt;/li&gt;
&lt;li&gt;🔴 A severity rating&lt;/li&gt;
&lt;li&gt;📋 Three concrete next steps&lt;/li&gt;
&lt;li&gt;📄 A document checklist&lt;/li&gt;
&lt;li&gt;✍️ An editable draft reply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every date and amount links back to the &lt;strong&gt;exact line of the original letter&lt;/strong&gt; it came from. If the model can't verify a claim against the extracted facts, it says so — no confident hallucinations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who would pay for this?&lt;/strong&gt;  Anyone who has ever frozen looking at a government envelope, hired a solicitor at £150/hour just to be told "this is a routine payment reminder", or simply had a letter in their second language. The realistic addressable market is anyone who receives official correspondence — which is everyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The letter never leaves your device.&lt;/strong&gt; No accounts, no cloud, no telemetry. That's the product differentiator and the privacy guarantee rolled into one.&lt;/p&gt;




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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frontend&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://letter-decoder.vercel.app" rel="noopener noreferrer"&gt;https://letter-decoder.vercel.app&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;React 19 app, deployed on Vercel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Public API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://letter-decoder-api-qvxs.onrender.com" rel="noopener noreferrer"&gt;https://letter-decoder-api-qvxs.onrender.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;FastAPI — runs in &lt;code&gt;ENGINE_MODE=mock&lt;/code&gt;, replays 14 canonical examples through the full SSE pipeline with realistic delays&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;For real decoding with a local model, clone the repo and run with Ollama (see below). The public endpoint intentionally uses mock mode so no real letters are ever uploaded to a server.&lt;/p&gt;
&lt;/blockquote&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/RAMBO-LC" rel="noopener noreferrer"&gt;
        RAMBO-LC
      &lt;/a&gt; / &lt;a href="https://github.com/RAMBO-LC/letter-decoder" rel="noopener noreferrer"&gt;
        letter-decoder
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Local-first, open-source app that explains official letters in plain language with open-weight models on your own machine. No cloud, no telemetry, no accounts.
    &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;Letter Decoder&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;"A patient friend read it for me, and now I know what to do."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667"&gt;&lt;img src="https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/359a78a6c36b079b424e81e8d4f42c736fee8b4bef8a291fd8048c5d55af7688/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4861636b746f626572666573742d323032362d6f72616e67652e737667"&gt;&lt;img src="https://camo.githubusercontent.com/359a78a6c36b079b424e81e8d4f42c736fee8b4bef8a291fd8048c5d55af7688/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4861636b746f626572666573742d323032362d6f72616e67652e737667" alt="Hacktoberfest 2026"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/a2370cd106be14faa767bfff42e60f33a09f2736258c0f8c239e35ded83ca5a9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31312532422d3337373641423f6c6f676f3d707974686f6e266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/a2370cd106be14faa767bfff42e60f33a09f2736258c0f8c239e35ded83ca5a9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31312532422d3337373641423f6c6f676f3d707974686f6e266c6f676f436f6c6f723d7768697465" alt="Python 3.11+"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/990fc4a3f2c07019530e00ff2beb0c9041b1f76af67cd8ea9beb2b8c310ae2da/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466173744150492d3030393638383f6c6f676f3d66617374617069266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/990fc4a3f2c07019530e00ff2beb0c9041b1f76af67cd8ea9beb2b8c310ae2da/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466173744150492d3030393638383f6c6f676f3d66617374617069266c6f676f436f6c6f723d7768697465" alt="FastAPI"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/5db4de9dcd72e7b8e95fe25f33f5520c571e9c3f93522d691a10cff804fb795d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656163742d31392d3631444146423f6c6f676f3d7265616374266c6f676f436f6c6f723d626c61636b"&gt;&lt;img src="https://camo.githubusercontent.com/5db4de9dcd72e7b8e95fe25f33f5520c571e9c3f93522d691a10cff804fb795d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656163742d31392d3631444146423f6c6f676f3d7265616374266c6f676f436f6c6f723d626c61636b" alt="React 19"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/34f43e33ebbeffbd08ad1db7e3c7b5f40d728c58f28bc214ac571e1f553d6abe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f496e666572656e63652d4f6c6c616d612d626c61636b"&gt;&lt;img src="https://camo.githubusercontent.com/34f43e33ebbeffbd08ad1db7e3c7b5f40d728c58f28bc214ac571e1f553d6abe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f496e666572656e63652d4f6c6c616d612d626c61636b" alt="Ollama"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/1d006852bd0d77325362dee3bad4e857f54e6034f02c3c1a47f9bae4c6b09377/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52756e732d3130302532352532306f66666c696e652d627269676874677265656e"&gt;&lt;img src="https://camo.githubusercontent.com/1d006852bd0d77325362dee3bad4e857f54e6034f02c3c1a47f9bae4c6b09377/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52756e732d3130302532352532306f66666c696e652d627269676874677265656e" alt="Offline"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A local-first, open-source app that explains official letters in plain language.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Tax notices, fines, insurance rejections, bank letters, landlord notices — drop one in as a
photo, PDF, screenshot, or pasted text, and get back an &lt;strong&gt;answer card&lt;/strong&gt;: a one-line verdict, a
deadline countdown, severity, three concrete next steps, a document checklist, and an editable
draft reply. Every date and amount links back to the exact line of the original letter it came
from.&lt;/p&gt;
&lt;p&gt;No cloud calls. No telemetry. No accounts. &lt;strong&gt;The letter never leaves your device.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Live Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frontend&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://letter-decoder.vercel.app" rel="nofollow noopener noreferrer"&gt;https://letter-decoder.vercel.app&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;React app (Vercel)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://letter-decoder-api-qvxs.onrender.com" rel="nofollow noopener noreferrer"&gt;https://letter-decoder-api-qvxs.onrender.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;FastAPI engine (Render)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;The public API runs &lt;code&gt;ENGINE_MODE=mock&lt;/code&gt;, replaying canonical examples through the same
endpoints and SSE event streams with realistic delays. For real decoding with an open-weight
model, run it locally…&lt;/p&gt;
&lt;/blockquote&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/RAMBO-LC/letter-decoder" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Quick start with a real model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Terminal 1 — start the inference server&lt;/span&gt;
ollama serve
ollama pull qwen2.5:7b

&lt;span class="c"&gt;# Terminal 2 — start the app&lt;/span&gt;
git clone https://github.com/RAMBO-LC/letter-decoder.git
&lt;span class="nb"&gt;cd &lt;/span&gt;letter-decoder
uv &lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="nt"&gt;--all-extras&lt;/span&gt;
uv run python &lt;span class="nt"&gt;-m&lt;/span&gt; api.main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://127.0.0.1:8000&lt;/code&gt; — everything runs fully offline from here.&lt;/p&gt;




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

&lt;p&gt;The core design principle is: &lt;strong&gt;code finds facts, the model explains them.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Input] → Preprocess → Extract Text → Deterministic Facts → Classify → Notice Pack → LLM Explain → Verify → Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Preprocess&lt;/strong&gt; (&lt;code&gt;engine/preprocess.py&lt;/code&gt;) — OpenCV deskew and denoise for photos/scans.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract text&lt;/strong&gt; (&lt;code&gt;engine/extract_text.py&lt;/code&gt;) — native PDF text extraction, falling back to Tesseract OCR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic extraction&lt;/strong&gt; (&lt;code&gt;engine/deterministic_extract.py&lt;/code&gt;) — regex + &lt;code&gt;dateparser&lt;/code&gt; pull every date, amount, and reference number from the raw text. The LLM &lt;strong&gt;never sees a blank slate&lt;/strong&gt;: facts are pre-extracted before it is invoked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Classify&lt;/strong&gt; (&lt;code&gt;engine/classifier.py&lt;/code&gt;) — keyword and embedding matching identifies the notice type and loads the right &lt;strong&gt;notice pack&lt;/strong&gt; (a YAML file per country/type in &lt;code&gt;notices/&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM Explain&lt;/strong&gt; (&lt;code&gt;engine/llm_constrained.py&lt;/code&gt;) — &lt;a href="https://ollama.ai" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; runs locally; the default model is &lt;strong&gt;Qwen 2.5 7B&lt;/strong&gt; (fully open weights). JSON-constrained output means the model can only produce the schema the verifier expects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; (&lt;code&gt;engine/verifier.py&lt;/code&gt;) — every factual claim in the LLM output is checked against the deterministically extracted facts. A fact the model invented that wasn't in the source text fails verification — you get a clean error, not a confident lie.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Open-Source AI Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local inference&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ollama.ai" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default model&lt;/td&gt;
&lt;td&gt;&lt;a href="https://huggingface.co/Qwen/Qwen2.5-7B-Instruct" rel="noopener noreferrer"&gt;Qwen 2.5 7B&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OCR&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/tesseract-ocr/tesseract" rel="noopener noreferrer"&gt;Tesseract&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image processing&lt;/td&gt;
&lt;td&gt;&lt;a href="https://opencv.org" rel="noopener noreferrer"&gt;OpenCV&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API framework&lt;/td&gt;
&lt;td&gt;&lt;a href="https://fastapi.tiangolo.com" rel="noopener noreferrer"&gt;FastAPI&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;&lt;a href="https://react.dev" rel="noopener noreferrer"&gt;React 19&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every layer is open source. You can swap &lt;code&gt;qwen2.5:7b&lt;/code&gt; for Gemma, Llama, Mistral, or a fine-tuned checkpoint by changing one environment variable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contributing is Data, Not Code
&lt;/h3&gt;

&lt;p&gt;Most contributions to this project are YAML files, not Python PRs. Adding support for a new country is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# notices/fr/tax_reminder.yaml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Avis&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;de&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;rappel&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fiscal"&lt;/span&gt;
&lt;span class="na"&gt;keywords&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Trésor&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;public"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DGFIP"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;avis&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;d'imposition"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;severity_default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;act_soon&lt;/span&gt;
&lt;span class="na"&gt;mock_simple&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;French&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tax&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;reminder."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. CI validates it against the JSON Schema automatically.&lt;/p&gt;




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

&lt;p&gt;A letter contains income, legal status, financial history, and sometimes your immigration situation. Explaining it with a closed API means uploading it.&lt;/p&gt;

&lt;p&gt;There is no enterprise tier, privacy toggle, or data-processing agreement that un-does the fact that your letter travelled to someone else's data center. With an open local model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The letter structurally never leaves the machine.&lt;/strong&gt; This isn't a policy — it's enforced: &lt;code&gt;tests/test_local_only.py&lt;/code&gt; fails the CI build if &lt;em&gt;any&lt;/em&gt; code path attempts an outbound network call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero marginal cost.&lt;/strong&gt; A family that gets ten letters a year pays nothing extra after the initial setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditability.&lt;/strong&gt; The verifier that proves "the model never invents a deadline" is code you can read, fork, and run yourself. You don't have to trust a vendor's marketing copy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappability.&lt;/strong&gt; Communities can fine-tune a small model on their country's letter formats — a GDPR-compliant, locally-hosted specialist — without any API negotiation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open weights made this project's privacy guarantee credible. A closed API could promise the same guarantee; open weights prove it.&lt;/p&gt;




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




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

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hacktoberfest Open-Source AI Challenge — Week 2: Side Hustle&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Field Notes: A Bird Journal That Writes Itself, Offline, While I Keep My Phone in My Pocket</title>
      <dc:creator>Raj Ambolikar</dc:creator>
      <pubDate>Sun, 11 Oct 2026 15:27:09 +0000</pubDate>
      <link>https://dev.to/rambolc/field-notes-a-bird-journal-that-writes-itself-offline-while-i-keep-my-phone-in-my-pocket-37id</link>
      <guid>https://dev.to/rambolc/field-notes-a-bird-journal-that-writes-itself-offline-while-i-keep-my-phone-in-my-pocket-37id</guid>
      <description>&lt;h1&gt;
  
  
  devchallenge, #hf26challenge
&lt;/h1&gt;

&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;Most birding apps want you to stare at your screen while you're trying to listen. I wanted the opposite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Field Notes&lt;/strong&gt; is a local-first bird journal that turns a walk into a field log. I start a recording on my phone, put it in my pocket, and go outside. Back at my laptop, an open-weight bird sound model analyzes the recording, logs detected species to a local database, updates my life list, and generates a short journal entry about the walk.&lt;/p&gt;

&lt;p&gt;The interface has two main jobs: letting me start a recording and helping me read the recap. Everything in between is designed to stay out of the way.&lt;/p&gt;

&lt;p&gt;I built it for people who would rather pay attention to the birds than their screens, and who want to explore AI-assisted birding without sending their recordings and location data to a cloud service.&lt;/p&gt;

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

&lt;p&gt;Watch Field Notes in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stream.new/v/Fa1Wr022RW1o8KedUbmUSoLH00iQqbBYukOJV6XCsH69k" rel="noopener noreferrer"&gt;&lt;strong&gt;▶ Watch the Field Notes Demo&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;GitHub repository:&lt;/strong&gt; &lt;a href="https://github.com/RAMBO-LC/mlh-d2" rel="noopener noreferrer"&gt;https://github.com/RAMBO-LC/mlh-d2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The README includes setup instructions, model information, license links, and commands for reproducing the project's tested behavior.&lt;/p&gt;

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

&lt;p&gt;The pipeline is designed to run locally on my 16 GB M5 MacBook, using the CPU rather than a dedicated GPU.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Bird identification with BirdNET
&lt;/h3&gt;

&lt;p&gt;Field Notes uses &lt;code&gt;birdnet-analyzer&lt;/code&gt; 2.4.0 to analyze audio in three-second windows and identify potential bird species. BirdNET can use location and time of year to narrow its candidate species.&lt;/p&gt;

&lt;p&gt;The distinction between model weights and software licenses matters here: BirdNET's code is MIT-licensed, while its model weights are licensed under CC BY-NC-SA 4.0. That means the weights have non-commercial and share-alike conditions; I don't treat them as unrestricted commercial assets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;License:&lt;/strong&gt; &lt;a href="https://github.com/birdnet-team/BirdNET-Analyzer" rel="noopener noreferrer"&gt;BirdNET Analyzer repository&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Journal generation
&lt;/h3&gt;

&lt;p&gt;The journal is designed around a locally running language model through Ollama, with Gemma 3 as the intended model.&lt;/p&gt;

&lt;p&gt;The journal's job is to turn the detection log into a readable account of the walk, not to invent wildlife sightings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model and terms:&lt;/strong&gt; &lt;a href="https://ai.google.dev/gemma" rel="noopener noreferrer"&gt;Gemma&lt;/a&gt; · &lt;a href="https://ai.google.dev/gemma/terms" rel="noopener noreferrer"&gt;Gemma Terms of Use&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Before publishing, specify whether the journal was generated by actual Gemma output or by a deterministic template. Don't claim a successful live model run unless you've verified it.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Local storage and interface
&lt;/h3&gt;

&lt;p&gt;SQLite stores walks, detections, and the life list. A lightweight local web interface supports recording uploads, journal recaps, exports, and deleting saved data.&lt;/p&gt;

&lt;p&gt;The goal is to keep the workflow understandable and the data under the user's control.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Development tools
&lt;/h3&gt;

&lt;p&gt;I built the project with OpenCode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping AI-Generated Journals Grounded
&lt;/h2&gt;

&lt;p&gt;Language models can confidently invent species, so Field Notes is designed with safeguards.&lt;/p&gt;

&lt;p&gt;The journal-generation instructions tell the model to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the detection log as the source of facts about the walk.&lt;/li&gt;
&lt;li&gt;Describe low-confidence identifications as uncertain.&lt;/li&gt;
&lt;li&gt;Label general bird trivia as unverified rather than presenting it as an observation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A validation step checks the generated journal against the detection log. If it mentions a species that wasn't detected, the system attempts one regeneration before falling back to a plain template.&lt;/p&gt;

&lt;p&gt;The test suite includes a case in which the journal invents a Bald Eagle, allowing the validation logic to be checked against a concrete failure.&lt;/p&gt;

&lt;p&gt;These safeguards don't establish that every identification is correct. They address a narrower problem: preventing the journal from presenting unsupported species sightings as facts.&lt;/p&gt;

&lt;p&gt;The initial synthetic-audio test produced zero detections, as expected. That established a basic test case, not real-world accuracy. Field testing is necessary to evaluate how the system performs with actual outdoor recordings.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  It can run locally
&lt;/h3&gt;

&lt;p&gt;The architecture is designed to keep audio analysis, journal generation, and storage on the user's machine. Local inference avoids making a cloud AI service a requirement for every walk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; claim fully offline operation only after testing the complete workflow with external network access blocked.&lt;/p&gt;

&lt;h3&gt;
  
  
  My recordings and location stay under my control
&lt;/h3&gt;

&lt;p&gt;Recordings and audio clips are stored locally, and the log lives in a local SQLite database. GPS is disabled by default.&lt;/p&gt;

&lt;p&gt;The project also provides &lt;code&gt;fieldnotes wipe --yes&lt;/code&gt; and a delete-all button for removing saved data. These are intended to make data deletion explicit rather than leaving users to hunt through application files.&lt;/p&gt;

&lt;h3&gt;
  
  
  No per-walk API charge
&lt;/h3&gt;

&lt;p&gt;The intended workflow doesn't require a paid cloud inference API or an API key. Running locally still requires suitable hardware, storage, and the time needed to download and initialize the models.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open models require reading the fine print
&lt;/h3&gt;

&lt;p&gt;Open innovation isn't just about being able to download a model. The licenses and terms determine what people can actually do with it.&lt;/p&gt;

&lt;p&gt;BirdNET's model weights carry non-commercial and share-alike conditions. Gemma 3 has its own terms of use rather than an OSI-approved open-source license. Both distinctions matter when building something that other people might want to reuse.&lt;/p&gt;

&lt;h3&gt;
  
  
  The trade-offs are real
&lt;/h3&gt;

&lt;p&gt;Local AI isn't automatically the easiest option.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Setup takes time.&lt;/strong&gt; Model downloads can be substantial, and first-time setup is more involved than calling a hosted API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardware matters.&lt;/strong&gt; Inference speed depends on the machine and the models being used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detection isn't certainty.&lt;/strong&gt; Background noise, overlapping calls, and similar-sounding species can make identification difficult.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generated prose needs validation.&lt;/strong&gt; A fluent journal entry isn't proof that the underlying identification is correct.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is an experiment in making local AI useful outdoors, not a claim that local models have eliminated these limitations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Walk
&lt;/h2&gt;

&lt;p&gt;This is the part that matters most: taking the project outside and seeing what happens when the inputs aren't synthetic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;When and where:&lt;/strong&gt; [Date, general location or habitat, and walk duration]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What it identified correctly:&lt;/strong&gt; [Species you independently confirmed by ear or with a field guide]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What it got wrong:&lt;/strong&gt; [False positives or incorrect identifications, including confidence scores if available]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What it missed:&lt;/strong&gt; [Birds you heard but the system didn't log]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One surprise:&lt;/strong&gt; [A specific moment, sound, or result from the walk]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screen time:&lt;/strong&gt; [What you actually did with your phone during the walk]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point isn't to prove that the model is perfect. It's to find out whether the tool helps me spend more time listening and less time looking at a screen.&lt;/p&gt;

&lt;p&gt;[Add one closing sentence in your own voice about whether Field Notes made the walk better.]&lt;/p&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; Include this only if you actually ran Gemma locally and verified its journal output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other challenge categories:&lt;/strong&gt; Mention any additional category only if the project genuinely qualifies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Solo submission.&lt;/em&gt;&lt;/p&gt;

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