<?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: TAIL</title>
    <description>The latest articles on DEV Community by TAIL (@godofzap).</description>
    <link>https://dev.to/godofzap</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%2F4204117%2F1dfed1e8-c38a-4d77-b2b0-d39b21a25f63.jpeg</url>
      <title>DEV Community: TAIL</title>
      <link>https://dev.to/godofzap</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/godofzap"/>
    <language>en</language>
    <item>
      <title>Sloth Vault</title>
      <dc:creator>TAIL</dc:creator>
      <pubDate>Sat, 24 Oct 2026 14:51:45 +0000</pubDate>
      <link>https://dev.to/godofzap/sloth-vault-41k6</link>
      <guid>https://dev.to/godofzap/sloth-vault-41k6</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Sloth Vault is a lazy filing system for people whose folders are a landfill. Point it at a folder and a local Gemma model reads each file (text, the first page of PDFs, even photos) and gives it a proper name, like &lt;code&gt;2026-10-24_airtel-broadband-invoice.pdf&lt;/code&gt; instead of &lt;code&gt;IMG_4821.jpg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It then files everything into a predictable layout, &lt;code&gt;Category / Year / Month&lt;/code&gt;, and builds a searchable &lt;code&gt;INDEX.csv&lt;/code&gt; plus a README of the rules, so anyone can find things without asking the person who set it up. Everything is logged, so one command undoes the whole run.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; the unsorted folder, listed with &lt;code&gt;tree /f&lt;/code&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%2Fj0i4m9ziok9jfcf5ibn2.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%2Fj0i4m9ziok9jfcf5ibn2.png" alt="Terminal output of the tree /f command listing the unsorted image files in a single messy folder" width="735" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dry run:&lt;/strong&gt; Sloth Vault plans the tidy-up without moving anything.&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%2Fn0aleddx4zfkz9zuj8ao.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%2Fn0aleddx4zfkz9zuj8ao.png" alt="Terminal showing Sloth Vault running a dry run with the live progress display while Gemma reads each file" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The plan:&lt;/strong&gt; A before and after table of original file names and their new names and folders.&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%2F1jfzyhqhcpk7yn68nnkl.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%2F1jfzyhqhcpk7yn68nnkl.png" alt="Dry run result table comparing each original file name with its new dated name and destination folder" width="799" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; the sorted vault in File Explorer after we run with &lt;code&gt;--apply&lt;/code&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%2Fre7y95qxltll9v5nhmqc.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%2Fre7y95qxltll9v5nhmqc.png" alt="File Explorer window showing the sorted vault with organised category folders" width="799" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The index:&lt;/strong&gt; every file's new path, original name, summary and tags, searchable in &lt;code&gt;INDEX.csv&lt;/code&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%2Fb0gy769236sog1v5qfrv.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%2Fb0gy769236sog1v5qfrv.png" alt="Contents of INDEX.csv listing each filed image with its new path, original name, summary and tags" width="795" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The final structure:&lt;/strong&gt; the same &lt;code&gt;tree /f&lt;/code&gt; command on the sorted vault, showing the category, year and month hierarchy.&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%2F1lr8aw3wagszuskfgs9g.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%2F1lr8aw3wagszuskfgs9g.png" alt="Terminal output of tree /f for the sorted vault showing the nested category, year and month folders with renamed files" width="741" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/GodOfZap/Sloth-Vault" rel="noopener noreferrer"&gt;https://github.com/GodOfZap/Sloth-Vault&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; Gemma 3 (4B), open-weight, served locally through Ollama. Gemma's vision reads photos and names them by what they show.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Glue:&lt;/strong&gt; a single Python script that asks Gemma for strict JSON (category, title, summary, tags) using Ollama's JSON mode. Obvious file types are sorted by extension rules, so the model only does the thinking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety:&lt;/strong&gt; it defaults to a dry run and never overwrites a file (collisions get a numeric suffix). Exact duplicates are parked in &lt;code&gt;_Duplicates&lt;/code&gt; instead of deleted, and every move is logged for &lt;code&gt;--undo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extras:&lt;/strong&gt; &lt;code&gt;--find&lt;/code&gt; searches the vault, &lt;code&gt;--watch&lt;/code&gt; tidies new files as they arrive, and a live terminal progress bar shows what the sloth is doing.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Your folders might include tax forms, résumés, screenshots, bank statements and many more. With an open-weight model, none of that is uploaded to anyone's server. It also works offline, costs nothing per file, and I can swap in a bigger or smaller Gemma, or change the categories and prompt, with a one-line edit. A closed API would mean sending my private files to a third party and paying per call to organise them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;I ran Sloth Vault on a camera-roll folder full of photos named things like &lt;code&gt;650028291_18101274937925214_..._n.jpg&lt;/code&gt;. In one dry run, Gemma (running locally, 4B) looked at each photo and proposed a name and a home:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;28341743-d6fa-...jpg&lt;/code&gt; → &lt;code&gt;04_Images/2026/2026-04/2026-04-09_cloud-computing-workshop.jpg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;650028291_..._n.jpg&lt;/code&gt; → &lt;code&gt;04_Images/2026/2026-04/2026-04-08_graduation-ceremony.jpg&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Honest numbers from that run: 3 files, about 6.7 seconds each on my machine, 1,453 tokens in total, and zero cost. Three files is too small to beat doing it by hand, so the payoff is in what happens at scale: at that speed, 100 files is roughly 11 minutes of waiting for the model. That's time I can spend elsewhere, because I start it and walk away (or leave &lt;code&gt;--watch&lt;/code&gt; running). Tidying 100 files by hand would take me far longer, and the names would be worse.&lt;/p&gt;

&lt;p&gt;The bigger win is that the result is findable. Every file lands in a dated folder and gets a searchable line in &lt;code&gt;INDEX.csv&lt;/code&gt;, so "that workshop photo" becomes &lt;code&gt;--find workshop&lt;/code&gt; instead of scrolling through hundreds of numbered files.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Best Use of Gemma&lt;/li&gt;
&lt;/ul&gt;

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