<?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: Yash Singh</title>
    <description>The latest articles on DEV Community by Yash Singh (@yash6012).</description>
    <link>https://dev.to/yash6012</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4183905%2F62a0f4a0-ee99-4b35-8337-49796feafee6.webp</url>
      <title>DEV Community: Yash Singh</title>
      <link>https://dev.to/yash6012</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yash6012"/>
    <language>en</language>
    <item>
      <title>Your Abandoned Repos Deserve an Ofrenda: Meet Graveshell</title>
      <dc:creator>Yash Singh</dc:creator>
      <pubDate>Sat, 31 Oct 2026 16:34:43 +0000</pubDate>
      <link>https://dev.to/yash6012/your-abandoned-repos-deserve-an-ofrenda-meet-graveshell-2ld0</link>
      <guid>https://dev.to/yash6012/your-abandoned-repos-deserve-an-ofrenda-meet-graveshell-2ld0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26"&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Graveshell&lt;/strong&gt; is &lt;em&gt;"a haunted terminal that whispers about your commands, and an ofrenda for the projects you let die."&lt;/em&gt; 👻&lt;/p&gt;

&lt;p&gt;Every developer has a dark folder somewhere on their hard drive where unfinished ambitions go to rest: game prototypes, weekend micro-SaaS attempts, half-written CLI tools, and repos whose last commit was a hurried &lt;code&gt;WIP: fix bug&lt;/code&gt; from two years ago. We usually feel guilty about them, or pretend they don't exist.&lt;/p&gt;

&lt;p&gt;For the "Ghost in the Machine" theme (Halloween on October 31 and Día de los Muertos on November 1-2), I built around two traditions. Instead of hiding the ghosts in our machines, Graveshell welcomes them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mortimer, the terminal ghost 💀&lt;/strong&gt;: a sarcastic sysadmin who died in a cold server room in 1987. He watches your terminal and reacts to "omens": failed commands, force-pushes, &lt;code&gt;rm -rf&lt;/code&gt;, repeated frantic commands, and typos like &lt;code&gt;gti&lt;/code&gt; instead of &lt;code&gt;git&lt;/code&gt;. He answers with one eerie, darkly funny sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Graveyard 🕯️&lt;/strong&gt;: run &lt;code&gt;graveshell graveyard&lt;/code&gt; and it finds git repos untouched for 90+ days, then holds a small ofrenda for each one. You get a gravestone with the real data (birth date, date of death, days dead, commit count, last commit message), and only after that does Mortimer write a short epitaph. With &lt;code&gt;--revive&lt;/code&gt;, it also shows uncommitted changes and the oldest &lt;code&gt;TODO&lt;/code&gt;, as a nudge to bring a project back to life.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything runs locally through Ollama. No cloud APIs, no pip packages, and it works with Wi-Fi turned off.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://drive.google.com/file/d/1N2PyNRi7gDRoJFtS2D0czM1kqcyqS6Yc/view?usp=sharing" rel="noopener noreferrer"&gt;Demo Video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The whole demo was recorded with Wi-Fi turned **off&lt;/em&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is a gravestone from the Graveyard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;💀 ENTERING THE GRAVEYARD (Dia de los Muertos Ofrenda)
Seeking git repositories resting for 90+ days in C:\Users\yash7...


         .-----------------------------------------------.
        /                   †  R.I.P.  †                  \
       |                                                   |
       |  Project:    MindForge                            |
       |  Born:       2026-06-28                           |
       |  Died:       2026-08-02                           |
       |  Resting:    90 days in darkness                  |
       |  Commits:    18 commits                           |
       |  Last words: "Production enhanc. push           " |
       |                                                   |
        \       🏵️   🕯️    OFRENDA DE REPOS    🕯️   🏵️  /
         '-----------------------------------------------'
       🕯️  Mortimer's Epitaph: "Forgotten code, a fleeting dream, born in darkness, died in haste, its purpose lost in the voidd, a mere whisper of what could have been."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And Mortimer reacting to a mistyped command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.------------------------------------------------------------------------.
|  [!] MORTIMER'S POST-MORTEM
|  Command:     gti
|  Exit Code:   127 (Command Not Found)
|  Suggested:   git (typo fix)
|  Omen:        command not found (exit 127)
|
|  Mortimer's Diagnosis:
|     Another soul trapped in this forsaken terminal, waiting
|     for the inevitable reboot. The poor guy must be having
|     some kind of existential crisis, stuck in a loop of
|     terminal typing like
'------------------------------------------------------------------------'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;a href="https://github.com/Yash6012/Graveshell" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try it yourself (Windows PowerShell):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;ollama&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pull&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;llama3.2:1b&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://github.com/Yash6012/Graveshell.git&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Graveshell&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;graveshell.py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;demo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Graveshell has strict constraints: &lt;strong&gt;Python 3 standard library only&lt;/strong&gt;, a single core file (&lt;code&gt;graveshell.py&lt;/code&gt;), and a local &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; instance running the small open-weight &lt;code&gt;llama3.2:1b&lt;/code&gt; model. There is nothing to &lt;code&gt;pip install&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The key design decisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain Python first.&lt;/strong&gt; The model never counts days, counts commits, or searches for files. Python and the local &lt;code&gt;git&lt;/code&gt; CLI work out the facts, and the real evidence prints &lt;em&gt;before&lt;/em&gt; any AI text appears.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micro-prompts.&lt;/strong&gt; The model sees at most 4 facts per call and writes ONE short sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redaction before inference.&lt;/strong&gt; API keys, tokens, passwords, &lt;code&gt;user:pass@&lt;/code&gt; URLs and Bearer headers become &lt;code&gt;[REDACTED]&lt;/code&gt; before anything reaches the model. Commands that start with a space are never sent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail silent.&lt;/strong&gt; If Ollama is down or too slow, Mortimer says nothing, so your prompt never hangs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A tiny model on purpose.&lt;/strong&gt; My laptop is weak, so I picked &lt;code&gt;llama3.2:1b&lt;/code&gt; and kept prompts short to stay fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built with an agent, then made my own.&lt;/strong&gt; I used Google's Antigravity to scaffold the project, then tested it, learned how it works, and adapted it for Windows, including the PowerShell hook.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;For this kind of tool, open and local AI is not just an alternative to a cloud API. It is what makes the idea possible at all.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Privacy.&lt;/strong&gt; A terminal is full of file paths, server names, half-finished ideas and the occasional pasted token. Sending every command to a third-party API would be a non-starter. With a local open-weight model, prompts only go to &lt;code&gt;127.0.0.1:11434&lt;/code&gt; on my own machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works offline.&lt;/strong&gt; A haunted terminal that needs the internet isn't haunted, it's just an API client. Graveshell runs on a plane, in a train tunnel, or with Wi-Fi switched off for the demo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free per command.&lt;/strong&gt; A ghost that can comment on any command you run would add up quickly on a metered API. Locally, each whisper costs nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable models.&lt;/strong&gt; One environment variable changes the ghost's brain, for example &lt;code&gt;GRAVESHELL_MODEL=mistral&lt;/code&gt;. I'm not tied to one vendor's model, pricing, or deprecation schedule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No dependence on a service that can disappear.&lt;/strong&gt; Graveshell exists to remember projects that died when their maker moved on. It would be ironic if Graveshell died because an API changed or shut down. Open weights and open code mean it keeps working as long as someone has a laptop.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>shell</category>
    </item>
    <item>
      <title>SlipSense: a receipt sorter that never leaves your laptop</title>
      <dc:creator>Yash Singh</dc:creator>
      <pubDate>Sun, 18 Oct 2026 18:28:50 +0000</pubDate>
      <link>https://dev.to/yash6012/slipsense-a-receipt-sorter-that-never-leaves-your-laptop-25p5</link>
      <guid>https://dev.to/yash6012/slipsense-a-receipt-sorter-that-never-leaves-your-laptop-25p5</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;Every quarter, my brother, who runs a freelance graphic design studio in Indore loses an entire weekend to a shoe box of crumpled paper slips, WhatsApp photos, and email PDF invoices. They type every line into a spreadsheet by hand. They tried commercial expense apps, but deleted them immediately: those apps upload receipts to third-party cloud servers. Receipts carry home addresses, personal bank details, client names, and tax numbers. For privacy-conscious freelancers and small businesses, the cloud is a non-starter.&lt;/p&gt;

&lt;p&gt;I built SlipSense to solve this. SlipSense is an open-source, local receipt sorter. You point it at a folder on your computer, and it extracts the data, validates the math, flags questionable rows, and organizes files into clean accounting categories. It runs entirely on your local machine using an open vision model in Ollama. Your files never touch an external server, and it works with Wi-Fi switched off.&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%2Fuemooe814832vj2f7ldy.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%2Fuemooe814832vj2f7ldy.png" alt="Home Page" width="800" height="403"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The SlipSense dashboard: point to an input folder of receipts, confirm local Ollama status, and process in one click.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Who would pay, and how
&lt;/h3&gt;

&lt;p&gt;The target audience is solo freelancers, tax consultants, and small shop owners who track business expenses for deductions. Cloud tools charge \$10 to \$30 every month for features a solo operator rarely uses.&lt;/p&gt;

&lt;p&gt;The product model is a simple one-time desktop license or an annual "tax season pack" priced at INR 499 for standalone offline use.&lt;/p&gt;

&lt;p&gt;To be completely clear: I have not charged anyone yet, and SlipSense currently has zero paying customers.&lt;/p&gt;
&lt;h3&gt;
  
  
  How it outputs data
&lt;/h3&gt;

&lt;p&gt;SlipSense normalizes every document into nine standard columns:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Status | Vendor | Sub Total | Tax | Total | Currency | Category | Date | Reason&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is a real example from my test runs on &lt;code&gt;receipt_01_amazon.jpg&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;Sub Total&lt;/th&gt;
&lt;th&gt;Tax&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;th&gt;Currency&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;td&gt;Amazon India&lt;/td&gt;
&lt;td&gt;1101.69&lt;/td&gt;
&lt;td&gt;197.31&lt;/td&gt;
&lt;td&gt;1299.00&lt;/td&gt;
&lt;td&gt;INR&lt;/td&gt;
&lt;td&gt;Software&lt;/td&gt;
&lt;td&gt;2024-09-12&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On this receipt, the tax was split into 9% CGST (₹98.66) and 9% SGST (₹98.66). SlipSense extracted both tax lines, summed them into a single tax figure (₹197.31), verified that &lt;code&gt;1101.69 + 197.31 = 1299.00&lt;/code&gt;, matched the category from &lt;code&gt;categories.yaml&lt;/code&gt;, and passed the validation check.&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%2F6n8vqzwiyxq2sqpp16cs.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%2F6n8vqzwiyxq2sqpp16cs.png" alt="Data Extraction" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The review table showing extracted fields, currency tags, and automatic Needs-review flags.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Catching errors with human-in-the-loop review
&lt;/h3&gt;

&lt;p&gt;A small local model will make mistakes. SlipSense assumes the model will fail on difficult images. Instead of blindly trusting model outputs, rule-based verification checks the numbers. If a vendor is missing, if total is zero or negative, if subtotal plus tax differs from the total by more than 1%, or if the model required a retry, the row is flagged &lt;code&gt;Needs review&lt;/code&gt; with a plain-English reason.&lt;/p&gt;

&lt;p&gt;Flagged rows automatically sort to the top of the table. Clicking any row opens an inspector showing the original receipt side-by-side with editable fields.&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%2Fliqxgt0scsfan4330i0a.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%2Fliqxgt0scsfan4330i0a.png" alt="Receipt Preview" width="800" height="402"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Side-by-side inspector card: examine the document while confirming or editing flagged fields.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you export, SlipSense generates &lt;code&gt;expenses.csv&lt;/code&gt;, copies each receipt into &lt;code&gt;output/&amp;lt;Category&amp;gt;/YYYY-MM-DD_Vendor.ext&lt;/code&gt; without ever modifying your original files, and creates a &lt;code&gt;category_summary.csv&lt;/code&gt;. The summary groups totals strictly by category and currency, never adding US Dollars to Indian Rupees.&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%2Ffgo3d7fovlc4e56qvaio.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%2Ffgo3d7fovlc4e56qvaio.png" alt="Categorization" width="800" height="401"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Summary table aggregating expenses by category and currency, with grand totals.&lt;/em&gt;&lt;/p&gt;


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

&lt;p&gt;&lt;a href="https://drive.google.com/file/d/1q-nDRVvwY8ma927y978tcD1RsAx3Cwnj/view?usp=sharing" rel="noopener noreferrer"&gt;Demo Video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The video shows SlipSense running on a laptop with Wi-Fi physically disconnected: selecting a folder of raw receipts, extracting structured data in real time, reviewing a flagged item in the inspector, and exporting the final spreadsheet and categorized folders.&lt;/p&gt;


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

&lt;p&gt;&lt;a href="https://github.com/Yash6012/SlipSense" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SlipSense is licensed under the open-source &lt;strong&gt;MIT License&lt;/strong&gt; (Copyright (c) 2026 SlipSense Contributors).&lt;/p&gt;


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

&lt;p&gt;The entire pipeline runs locally in Python and Streamlit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Receipt Images &amp;amp; PDFs]
          │
          ▼
[image_prep.py] ── In-memory rendering (PyMuPDF at 110 DPI),
                   EXIF rotation fix (ImageOps.exif_transpose),
                   RGB conversion, in-memory resize (max_side &amp;lt;= 1000px),
                   JPEG quality 85 in io.BytesIO
          │
          ▼ (in-memory base64 string; zero disk temporary files)
      [Ollama] ── Model: qwen2.5vl:3b
                              JSON schema constraint via "format" parameter
          │
          ▼ (raw JSON response)
[Pydantic Validation] ── Coerce numeric strings, currency symbols, nullable fields
          │
          ▼
[validation.py] ── Deterministic checks: 1% arithmetic tolerance, future dates,
                   category matching, duplicate detection, tax derivation
          │
          ▼
[Streamlit UI (app.py)] ── Interactive review table, inspector card, inline edits
          │
          ▼
[exporter.py] ── expenses.csv, category_summary.csv,
                 safe copy into output/&amp;lt;Category&amp;gt;/YYYY-MM-DD_Vendor.ext
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Language &amp;amp; UI&lt;/strong&gt;: Python 3.13, Streamlit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local Vision Model&lt;/strong&gt;: &lt;code&gt;qwen2.5vl:3b&lt;/code&gt; running in Ollama on localhost:11434&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image &amp;amp; Document Processing&lt;/strong&gt;: Pillow (PIL), PyMuPDF (&lt;code&gt;fitz&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Validation &amp;amp; Parsing&lt;/strong&gt;: Pydantic v2, PyYAML, Pandas&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Image preparation settings
&lt;/h3&gt;

&lt;p&gt;All image pre-processing is configured in &lt;code&gt;config.yaml&lt;/code&gt; with zero hardcoded parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;max_side&lt;/code&gt;: 1000 pixels (longest dimension downscaled in memory; smaller images are never enlarged)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jpeg_quality&lt;/code&gt;: 85 (compressed in-memory via &lt;code&gt;io.BytesIO&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pdf_dpi&lt;/code&gt;: 110 (rendered directly from vector page to raster image)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;User originals are never touched, and no temporary resized images are written to disk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measured benchmark results
&lt;/h3&gt;

&lt;p&gt;I wrote a standalone benchmark script (&lt;code&gt;benchmark_sizes.py&lt;/code&gt;) that evaluates &lt;code&gt;qwen2.5vl:3b&lt;/code&gt; on the same test receipts across three different resolutions (&lt;code&gt;max_side&lt;/code&gt; = 1400, 1000, 800).&lt;/p&gt;

&lt;p&gt;Here are the real measured numbers from &lt;code&gt;benchmark_report.md&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;max_side&lt;/th&gt;
&lt;th&gt;Average seconds per file&lt;/th&gt;
&lt;th&gt;Files flagged "Needs review"&lt;/th&gt;
&lt;th&gt;Total-field accuracy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1400&lt;/td&gt;
&lt;td&gt;36.50s&lt;/td&gt;
&lt;td&gt;0 / 5&lt;/td&gt;
&lt;td&gt;100.0% (5/5)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;8.57s&lt;/td&gt;
&lt;td&gt;0 / 5&lt;/td&gt;
&lt;td&gt;100.0% (5/5)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;800&lt;/td&gt;
&lt;td&gt;9.28s&lt;/td&gt;
&lt;td&gt;0 / 5&lt;/td&gt;
&lt;td&gt;100.0% (5/5)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  A failure I hit
&lt;/h3&gt;

&lt;p&gt;When testing resolution scaling, I initially tried sending larger images (&lt;code&gt;max_side = 1400&lt;/code&gt;) believing higher resolution would yield better field extraction.&lt;/p&gt;

&lt;p&gt;Instead, I hit a massive latency cliff. Vision transformers tokenize images into fixed-size visual patches. At 1400px, complex receipts like &lt;code&gt;receipt_03_invoice_consulting.jpg&lt;/code&gt; and &lt;code&gt;receipt_04_aws.jpg&lt;/code&gt; caused token counts to swell, spiking latency from 8.5 seconds up to &lt;strong&gt;56.21s&lt;/strong&gt; and &lt;strong&gt;57.37s&lt;/strong&gt; per document on my machine. Worse, accuracy did not improve by a single percent: &lt;code&gt;max_side = 1000&lt;/code&gt; achieved identical 100% total-field accuracy at &lt;strong&gt;8.57s average&lt;/strong&gt;—over 4.25x faster. Downscaling to 1000px proved essential for running locally without memory exhaustion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Four design decisions I defend
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rule-based code decides trust, not model confidence scores&lt;/strong&gt;: Vision models frequently hallucinate high confidence on wrong numbers. My validation code checks arithmetic (&lt;code&gt;subtotal + tax == total&lt;/code&gt;), verifies date boundaries, and flags discrepancies deterministically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model never guesses&lt;/strong&gt;: If a field is illegible, the prompt instructs the model to output &lt;code&gt;null&lt;/code&gt;. SlipSense then flags the row for human review instead of fabricating numbers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Original files are sacred&lt;/strong&gt;: SlipSense only reads originals. Copies are placed into category folders with sanitized names, and collision counters prevent overwrites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Needs-review rows sort to the top&lt;/strong&gt;: In a folder of 50 receipts, a user should not have to hunt for the three that need human attention.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Absolute privacy and offline reliability&lt;/strong&gt;: Receipt data contains bank details, vendor contacts, and private purchases. With open models and local runtimes like Ollama, data never leaves the device. The application functions in a remote cabin or on an airplane with Wi-Fi switched off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero marginal cost&lt;/strong&gt;: Closed vision APIs charge per page or per API call ([CHECK CURRENT PRICING, e.g. $0.01 to $0.05 per document]). For an irregular freelancer processing 30 receipts one month and none the next, subscription fees and API meters add friction. An open model running locally costs zero cents per file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model independence and longevity&lt;/strong&gt;: Closed cloud APIs deprecate endpoints, adjust system prompts, and change rate limits without warning. In SlipSense, switching to another model requires changing one line in &lt;code&gt;config.yaml&lt;/code&gt; (&lt;code&gt;model_name: "qwen2.5vl:3b"&lt;/code&gt;). The software remains operational ten years from now on local hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inspectable, customizable taxonomy&lt;/strong&gt;: Business categories vary across countries and industries. Instead of opaque cloud categories, SlipSense uses an open &lt;code&gt;categories.yaml&lt;/code&gt; and &lt;code&gt;examples.yaml&lt;/code&gt; that any user can adapt to their chart of accounts.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The honest counterweight
&lt;/h3&gt;

&lt;p&gt;A closed frontier model (like GPT-4o or Gemini 1.5 Pro) running on cloud TPU clusters would be faster in raw throughput and better at deciphering crumpled, handwritten cursive or faded thermal receipts. A 3B local model requires decent CPU/RAM, takes about 8.5 seconds per document on a laptop, and cannot reliably read illegible handwriting. I chose the local model anyway because for accounting documents, absolute data confidentiality outweighs cloud speed.&lt;/p&gt;




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

&lt;p&gt;I built SlipSense pairing with &lt;strong&gt;Google Antigravity&lt;/strong&gt;, &lt;strong&gt;Google AI Studio&lt;/strong&gt; an agentic AI coding environment. Antigravity handled file generation, wrote comprehensive pytest suites, ran background CLI commands to measure model latency, and helped refine image preparation logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;p&gt;To be transparent: SlipSense currently has no paying customers, and I have not charged anyone.&lt;/p&gt;

&lt;p&gt;I have reached out to several local shopkeepers and independent freelancers in my neighborhood to get early feedback on the offline workflow.&lt;/p&gt;




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

&lt;p&gt;I’m a backend developer, so ML was new ground for me. Tinker let me write a fine-tuning loop in plain Python without wrestling with GPUs, which meant I could actually focus on learning. I fine-tuned [MODEL] on [N] synthetic receipts and compared it with the base model: [REAL RESULT]. I used synthetic data only, since SlipSense exists to keep real receipts on the user’s laptop, and the final model still runs locally through Ollama.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Intro</title>
      <dc:creator>Yash Singh</dc:creator>
      <pubDate>Wed, 14 Oct 2026 06:53:36 +0000</pubDate>
      <link>https://dev.to/yash6012/intro-1ban</link>
      <guid>https://dev.to/yash6012/intro-1ban</guid>
      <description>&lt;p&gt;Hi, I'm Yash Singh!&lt;/p&gt;

&lt;p&gt;I'm a software and hardware enthusiast working in the world of Internet of Things. I love bridging the physical and digital worlds—connecting embedded systems, smart devices, and cloud architecture to build intelligent, connected solutions.&lt;/p&gt;

&lt;p&gt;I joined DEV to share my journey, document my projects, and connect with other engineers passionate about IoT, hardware, and scalable backend systems.&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>iot</category>
      <category>software</category>
    </item>
  </channel>
</rss>
