<?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: Bankole David </title>
    <description>The latest articles on DEV Community by Bankole David  (@devolabanks).</description>
    <link>https://dev.to/devolabanks</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%2F1268033%2F9a61fe21-b8a7-428e-a175-af18db4e3647.png</url>
      <title>DEV Community: Bankole David </title>
      <link>https://dev.to/devolabanks</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devolabanks"/>
    <language>en</language>
    <item>
      <title>Fallow Slow and Steady file triage</title>
      <dc:creator>Bankole David </dc:creator>
      <pubDate>Sun, 25 Oct 2026 14:20:51 +0000</pubDate>
      <link>https://dev.to/devolabanks/fallow-slow-and-steady-file-triage-lm6</link>
      <guid>https://dev.to/devolabanks/fallow-slow-and-steady-file-triage-lm6</guid>
      <description>&lt;h1&gt;
  
  
  Fallow Slow and Steady file triage (Hacktoberfest 2026, Week 3)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  devchallenge #hf26challenge #ai #opensource #python
&lt;/h1&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%2Fg36a6il1hssek00em425.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%2Fg36a6il1hssek00em425.png" alt="Fallow: sort a messy Downloads folder in minutes, with zero cloud upload" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady.&lt;/p&gt;

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

&lt;p&gt;Fallow is a local file-triage tool that rewards laziness: you label a small batch of files once, and it predicts archive / keep / delete for every other file in your Downloads folder, ranks the best archive candidates, proposes cleaner filenames, and builds a static HTML site you can publish. It never moves, renames or deletes anything — it only suggests.&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%2Fpzehlrveqtuiy7td1gby.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%2Fpzehlrveqtuiy7td1gby.png" alt="Field map of 260 files: 202 keep, 16 archive, 42 delete" width="799" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The old friction was "label ~200 files by hand." Fallow cuts that with &lt;code&gt;--autolabel --review&lt;/code&gt;: &lt;code&gt;collect --autolabel&lt;/code&gt; pre-marks obvious files (temp/cache → delete, old archives → archive, recent media/docs → keep), and &lt;code&gt;label --review&lt;/code&gt; only prompts for the ambiguous remainder. On a real 260-file folder, 158 files (61%) were auto-labeled; only 102 needed a human decision. Setup once, label the exceptions, sort the rest forever.&lt;/p&gt;

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

&lt;p&gt;A static page built from a real 260-file run — open it locally, no server required.&lt;/p&gt;

&lt;p&gt;&lt;a href="//site/index.html"&gt;&lt;code&gt;site/index.html&lt;/code&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%2Flo3n3j4v4drmphqs63sz.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%2Flo3n3j4v4drmphqs63sz.png" alt="What this run actually did" width="799" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;All CLI, CSV in / CSV out, no server, no database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/BANKOLEDO/fallow" rel="noopener noreferrer"&gt;https://github.com/BANKOLEDO/fallow&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Pipeline:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;collect&lt;/code&gt; — walks a directory, emits one CSV row per file (size, age, extension, folder, depth, name stats).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;label --review&lt;/code&gt; — crash-safe, resumable labelling; &lt;code&gt;--review&lt;/code&gt; skips auto-labeled rows.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;classify&lt;/code&gt; — trains on your labels, predicts the rest, prints honest holdout accuracy.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rename&lt;/code&gt; — proposes clean snake_case filenames via local Gemma through Ollama; never renames anything.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report&lt;/code&gt; — plain-text triage summary: counts, reclaimable GB, oldest archive candidates.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;site&lt;/code&gt; — static HTML from your real results; &lt;code&gt;--redact&lt;/code&gt; swaps real names for &lt;code&gt;file_0001.ext&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frtlb8x143jzrg7aqa3m7.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%2Frtlb8x143jzrg7aqa3m7.png" alt="Run order" width="799" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Classifier fallback chain (never hard-fails):&lt;/strong&gt; Local TabPFN → Prior Labs TabPFN API (&lt;code&gt;TABPFN_API_KEY&lt;/code&gt;) → scikit-learn RandomForest with a loud &lt;code&gt;[WARN] FALLBACK CLASSIFIER — results are NOT TabPFN&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%2Fyvoz4dx6d0y97bwd53la.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%2Fyvoz4dx6d0y97bwd53la.png" alt="TabPFN classify: 1.000 on a 35-row holdout" width="799" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open-weight models:&lt;/strong&gt; TabPFN (local, optional, licence-gated) and Gemma 3 270M via Ollama (optional, rename proposals only). Everything else runs offline with no API key.&lt;/p&gt;

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

&lt;p&gt;A file-triage tool shouldn't require uploading your Downloads folder to a cloud API just to get filename suggestions. Fallow's core — collect, label, classify, report — runs &lt;strong&gt;fully offline with no API key&lt;/strong&gt;. When TabPFN's licence step blocked headless on this machine, Fallow warned and fell back to the Prior Labs API instead of crashing. When Gemma 270M returned boilerplate JSON, Fallow kept the original name instead of inventing one. The failure mode is visible in the code, not hidden behind a vendor SDK.&lt;/p&gt;

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

&lt;p&gt;No DevRelay agent session recorded; this was built hand-to-keyboard and verified with &lt;code&gt;python -m pytest -q&lt;/code&gt; → &lt;strong&gt;22 passed.&lt;/strong&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%2Fj603hhf3p82j01gpulkl.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%2Fj603hhf3p82j01gpulkl.png" alt="Proof, not promises: tests, offline core, honest limits" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Setup takes a few minutes, once; daily effort after setup is near zero. Real run on 260 files (123.65 MB):&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%2Fnjew9rrt39vqvfs7x9kn.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%2Fnjew9rrt39vqvfs7x9kn.png" alt="Demo outputs: CSV/DOCX/PDF/MP3 artifacts" width="800" height="459"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FALLOW REPORT
=============
Files analysed: 260
Classifier:     TabPFN (Prior Labs API)
Holdout:        35/35 correct (accuracy 1.000)

Predicted action:
  archive    16   6.2%    9.30 MB
  keep      202  77.7%   99.00 MB
  delete     42  16.2%   21.36 MB

Reclaimable space (predicted delete): 0.02 GB (21.36 MB)
Average model confidence: 0.98 (lowest 0.53)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fallow triaged 260 files and found 0.02 GB that can likely be deleted. Nothing was moved, renamed or deleted.&lt;/p&gt;

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

&lt;p&gt;Week 3 awards one overall winner plus featured and partner categories. The ones I'm entering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of TabPFN&lt;/strong&gt; — local TabPFN classifier with Prior Labs API fallback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt; — Gemma 3 270M via Ollama for rename proposals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs&lt;/strong&gt; — ElevenLabs voice recap (&lt;code&gt;fallow_demo.mp3&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Sentry Agent Tracing&lt;/strong&gt; — Sentry traces on &lt;code&gt;fallow.classify&lt;/code&gt; and &lt;code&gt;fallow.prose&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Ultramarine (Paper Instruments)&lt;/strong&gt; — Ultramarine report prose&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Honest limits:&lt;/strong&gt; local TabPFN licence acceptance needs a browser/token and cannot complete headless on this machine (the Prior Labs API path was used instead); Gemma 270M return mostly boilerplate for rename proposals; the 1.000 accuracy was measured on a small synthetic-ish folder, so real-world results will vary.&lt;/p&gt;

&lt;p&gt;Full source: &lt;a href="https://github.com/BANKOLEDO/fallow" rel="noopener noreferrer"&gt;https://github.com/BANKOLEDO/fallow&lt;/a&gt;&lt;/p&gt;

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