<?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: Wal</title>
    <description>The latest articles on DEV Community by Wal (@walsoup).</description>
    <link>https://dev.to/walsoup</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%2F3913659%2F02ca55b2-1fa9-4add-a447-3f1d74b02214.png</url>
      <title>DEV Community: Wal</title>
      <link>https://dev.to/walsoup</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/walsoup"/>
    <language>en</language>
    <item>
      <title>serifu: translating manga in place on android</title>
      <dc:creator>Wal</dc:creator>
      <pubDate>Thu, 05 Nov 2026 15:22:44 +0000</pubDate>
      <link>https://dev.to/walsoup/serifu-translating-manga-in-place-on-android-21j0</link>
      <guid>https://dev.to/walsoup/serifu-translating-manga-in-place-on-android-21j0</guid>
      <description>&lt;p&gt;serifu is an android app that translates manga, manhua and manhwa in place. it screenshots the reader app you choose, finds the speech bubbles and draws english over them. no exporting pages, no pc pipeline.&lt;/p&gt;

&lt;p&gt;how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an accessibility service takes the screenshot when you tap a floating pill (or automatically when the page stops scrolling)&lt;/li&gt;
&lt;li&gt;the page gets split, bubbles get clustered, ocr reads them, the text gets translated and lettered back over the bubbles&lt;/li&gt;
&lt;li&gt;translation is on-device with ml kit, or an optional openai-compatible cloud endpoint if you want a stronger model&lt;/li&gt;
&lt;li&gt;the reading loop is a reducer: accessibility callbacks in, next state plus effects out&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;the app is three gradle modules: :core (plain kotlin), :app (the phone), and :linen (the design system the screens are built on).&lt;/p&gt;

&lt;p&gt;it bundles the full volume 1 of give my regards to black jack (209 pages, shared by the author under free secondary-use terms) so there's a sample to translate out of the box.&lt;/p&gt;

&lt;p&gt;it's 0.6.7-beta, still early development, and ocr and lettering will keep changing between releases. source-available under polyform noncommercial, not osi open source.&lt;/p&gt;

&lt;p&gt;code and apk: &lt;a href="https://github.com/walsoup/Serifu" rel="noopener noreferrer"&gt;https://github.com/walsoup/Serifu&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>ocr</category>
      <category>showdev</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Wal</dc:creator>
      <pubDate>Thu, 22 Oct 2026 23:58:28 +0000</pubDate>
      <link>https://dev.to/walsoup/-40p5</link>
      <guid>https://dev.to/walsoup/-40p5</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/tahary/slothtidy-a-zero-friction-100-local-ai-file-daemon-that-organizes-your-downloads-while-you-rest-2dfg" class="crayons-story__hidden-navigation-link"&gt;SlothTidy: A Zero-Friction, 100% Local AI File Daemon That Organizes Your Downloads While You Rest 🦥&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/tahary" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F4155629%2Fd02038ad-5862-45f7-8cda-cd112b8a3622.jpg" alt="tahary profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/tahary" class="crayons-story__secondary fw-medium m:hidden"&gt;
              taha
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                taha
                
                
              
              &lt;div id="story-author-preview-content-4892408" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/tahary" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F4155629%2Fd02038ad-5862-45f7-8cda-cd112b8a3622.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;taha&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/tahary/slothtidy-a-zero-friction-100-local-ai-file-daemon-that-organizes-your-downloads-while-you-rest-2dfg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 22&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/tahary/slothtidy-a-zero-friction-100-local-ai-file-daemon-that-organizes-your-downloads-while-you-rest-2dfg" id="article-link-4892408"&gt;
          SlothTidy: A Zero-Friction, 100% Local AI File Daemon That Organizes Your Downloads While You Rest 🦥
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/hacktoberfest"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;hacktoberfest&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/tahary/slothtidy-a-zero-friction-100-local-ai-file-daemon-that-organizes-your-downloads-while-you-rest-2dfg" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;12&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/tahary/slothtidy-a-zero-friction-100-local-ai-file-daemon-that-organizes-your-downloads-while-you-rest-2dfg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              3&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
          
          &lt;div class="only-sidebar-menu-item trusted-visible-block print-hidden align-center"&gt;
                
                    
                
          &lt;/div&gt;

        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>automation</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>paste-sloth: Ctrl+Space+V pastes your clipboard back tidied, by a 1-bit Gemma</title>
      <dc:creator>Wal</dc:creator>
      <pubDate>Thu, 22 Oct 2026 23:50:00 +0000</pubDate>
      <link>https://dev.to/walsoup/paste-sloth-ctrlspacev-pastes-your-clipboard-back-tidied-by-a-1-bit-gemma-201f</link>
      <guid>https://dev.to/walsoup/paste-sloth-ctrlspacev-pastes-your-clipboard-back-tidied-by-a-1-bit-gemma-201f</guid>
      <description>&lt;p&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥&lt;/p&gt;

&lt;p&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;/p&gt;

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

&lt;p&gt;paste-sloth is a background process. you copy the way you already do, and when the text is a mess you hold ctrl, press space, press V, and let go. the clipboard goes to a model, comes back restructured, and gets pasted into whichever window has focus. csv becomes a markdown table, json gets pretty-printed, logs become one entry per line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name,score,city
ada,10,lagos
grace,12,accra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the usual repair is a second app: paste into a chat, type "just the table", wait, select the reply, copy it, go back, paste. that whole loop is now one chord. the chord is awkward on purpose, so it never fires while you're typing, and the model is small enough that leaving it running feels lazy rather than expensive.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy2jzoztp8vbfg7qy74tf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy2jzoztp8vbfg7qy74tf.gif" alt="paste-sloth turning name,score,city into a markdown table" width="760" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the gif is a real &lt;code&gt;paste-sloth clean&lt;/code&gt; run against a stub server. the stub is rude on purpose: it answers with &lt;code&gt;Here is the table:&lt;/code&gt; and a code fence, so you can watch the tool strip both, check the numbers, and print the table. &lt;code&gt;paste-sloth clean&lt;/code&gt; restructures the clipboard once and prints the result - the easy way to see what the model does before the keyboard is involved.&lt;/p&gt;

&lt;p&gt;the installer is one line. it finds python 3.11 or newer, makes a venv, and opens a menu:&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;# macOS or Linux&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/walsoup/paste-sloth/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Windows&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://raw.githubusercontent.com/walsoup/paste-sloth/main/install.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0q60bbmm708c4u3ultqt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0q60bbmm708c4u3ultqt.gif" alt="the installer menu, choosing gemma at 1-bit" width="799" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;enter on the first row asks for a base url, a key, and a model name. down, then enter, is the local option: it installs ollama if it's missing and downloads gemma 4 e2b at 1-bit (IQ1_S, about 2.4 gb - google doesn't publish a 1-bit file, so it's an importance-matrix quant of the instruction-tuned weights), then writes the config and an autostart entry.&lt;/p&gt;

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

&lt;p&gt;the model does the one job a very small model can be asked to do. the code holds the pen for everything else.&lt;/p&gt;

&lt;p&gt;the request is a chat completion at temperature 0. the system prompt is short: reply with only the restructured text, keep every value, pick the structure that fits. before the reply touches the clipboard it gets checked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;code fences and one-line preambles ("here is...") are stripped&lt;/li&gt;
&lt;li&gt;if the reply contains a number the input never had, it's asked once more with a sterner prompt, then dropped. invented numbers are the worst failure for pasted text: a figure that looks right and isn't. dropped numbers are allowed, because stripping timestamps off a log is legitimate&lt;/li&gt;
&lt;li&gt;empty reply, error, or timeout (15s by default): nothing is pasted. your original text is still on the clipboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;the number check is the part i would not ship without:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;introduces_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;True when the output contains a number the input never had.

    Dropped numbers are allowed: stripping timestamps from a log is legitimate.
    Ordered-list markers the model adds (``1.``, ``2)``) are not data.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;invented&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;number_tokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ignore_list_markers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;number_tokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ignore_list_markers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invented&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the chord was the fiddly part, because space is also a spacebar. ctrl is forwarded as it happens. space is held back, and if you press another key or release space before V, the held space gets replayed, so autocomplete and input-method switching still work. V while both are held is the paste, and both keys are swallowed so the app doesn't also get a raw paste. a second chord while a request is in flight is ignored. ctrl+space+esc releases the keyboard and quits.&lt;/p&gt;

&lt;p&gt;on linux this is evdev with an exclusive grab plus a uinput virtual keyboard - wayland won't let an ordinary app watch every key or type into other windows, and a desktop shortcut can't express ctrl+space+V because space is not a modifier. the grab needs a one-time sudo setup, which &lt;code&gt;paste-sloth setup&lt;/code&gt; prints. windows and macos use pynput.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;the clipboard is the most private stream on the machine: passwords, tokens, a paragraph you haven't sent. "reformat what i just copied" is the last feature i'd hand to a service i can't inspect. with ollama on localhost, nothing you copy leaves the machine.&lt;/li&gt;
&lt;li&gt;open weights are what make this version possible. google released gemma, someone quantized it to 1 bit and published the file, ollama serves it on cpu with no account. every layer can be read, swapped, or run with the network off.&lt;/li&gt;
&lt;li&gt;it costs nothing to run, so there's no meter on a chord you hit all day.&lt;/li&gt;
&lt;li&gt;not locked in: &lt;code&gt;base_url&lt;/code&gt; takes any openai-compatible endpoint, local or hosted. your clipboard, your pick.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  what it can't do yet
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;windows and macos are written and unit-tested, but not run on real machines. macos will ask for accessibility and input monitoring, and ctrl+space may already switch input sources.&lt;/li&gt;
&lt;li&gt;on my own wayland box the uinput paste still needs the sudo setup, so a live ctrl+v from the virtual keyboard is unconfirmed there. wl-copy and wl-paste do work from a detached process, which is the part i could check without it.&lt;/li&gt;
&lt;li&gt;text only. images and files on the clipboard are ignored.&lt;/li&gt;
&lt;li&gt;a 1-bit model can still be wrong in ways a number check can't see.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;repo: &lt;a href="https://github.com/walsoup/paste-sloth" rel="noopener noreferrer"&gt;https://github.com/walsoup/paste-sloth&lt;/a&gt; - python 3.11, MIT.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>gemma</category>
      <category>opensource</category>
    </item>
    <item>
      <title>ClawbackMD: local Gemma drafts for AI-assisted insurance denials</title>
      <dc:creator>Wal</dc:creator>
      <pubDate>Sat, 17 Oct 2026 23:07:49 +0000</pubDate>
      <link>https://dev.to/walsoup/clawbackmd-local-gemma-drafts-for-ai-assisted-insurance-denials-1n3g</link>
      <guid>https://dev.to/walsoup/clawbackmd-local-gemma-drafts-for-ai-assisted-insurance-denials-1n3g</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;ClawbackMD drafts appeal packets for insurance denials that look AI-written on the payer side. You pick a denied claim, it reads the synthetic chart + payer policy, and it returns a verdict, quote-backed evidence, an editable letter, and peer-to-peer talking points.&lt;/p&gt;

&lt;p&gt;The model is optional. Default store is in-memory (no Docker). If Ollama/Gemma is down, cached human-reviewed drafts still demo the flow.&lt;/p&gt;

&lt;p&gt;Every letter is a draft. The UI asks for separate clinical and billing review logs. That is a demo attestation, not an e-signature and not NPI-bound.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Would Pay
&lt;/h2&gt;

&lt;p&gt;Hospital billing / RCM teams who already lose hours to AI-assisted denials. A local open-weight draft that only cites verbatim chart quotes is something a small billing shop could run on a laptop without sending PHI to a hosted API.&lt;/p&gt;

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

&lt;p&gt;Repo: &lt;a href="https://github.com/walsoup/clawbackmd" rel="noopener noreferrer"&gt;https://github.com/walsoup/clawbackmd&lt;/a&gt;&lt;br&gt;
Live demo: &lt;a href="https://clawbackmd.vercel.app" rel="noopener noreferrer"&gt;https://clawbackmd.vercel.app&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install
cp&lt;/span&gt; .env.example .env.local
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optional model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull gemma3
ollama serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five synthetic claims load on first open. Generate a draft on CLM-001 (appeal) and CLM-005 (documentation gap — query attending).&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;Open-weight path: Gemma via any OpenAI-compatible endpoint (&lt;code&gt;lib/llm.ts&lt;/code&gt;), usually local Ollama.&lt;/p&gt;

&lt;p&gt;Guardrails in &lt;code&gt;lib/validate.ts&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Evidence and policy quotes must be verbatim substrings of the source note/policy.&lt;/li&gt;
&lt;li&gt;Letter sentences with clinical atoms (labs, grades, durations, CPTs) must appear in validated evidence or claim facts; ungrounded sentences are stripped.&lt;/li&gt;
&lt;li&gt;The LLM may cite payer policy codes only. CFR / statute cites are attached server-side from &lt;code&gt;plan_type&lt;/code&gt;, not invented by the model.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uphold_denial&lt;/code&gt; means documentation gap — query the attending — not automatic write-off.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;UI uses the Linen design system (linen surface, forest primary, hairlines).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Open Innovation Matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PHI stays local.&lt;/strong&gt; Chart text never has to leave the machine if you run Gemma on Ollama.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost.&lt;/strong&gt; No per-token bill for a drafting loop billing staff would run all day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable model.&lt;/strong&gt; Point &lt;code&gt;LLM_BASE_URL&lt;/code&gt; / &lt;code&gt;LLM_MODEL&lt;/code&gt; at another OpenAI-compatible endpoint without rewriting the app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail closed on quotes.&lt;/strong&gt; If the model invents a finding, validators drop it instead of shipping a confident fake.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tradeoff: a weak local model needs the cached drafts and the quote scrubber. That is intentional for a demo that must not invent clinical facts.&lt;/p&gt;

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

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

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>roamshot: photo side quests for walks, with open models running on the phone</title>
      <dc:creator>Wal</dc:creator>
      <pubDate>Sun, 11 Oct 2026 11:10:53 +0000</pubDate>
      <link>https://dev.to/walsoup/roamshot-photo-side-quests-for-walks-with-open-models-running-on-the-phone-250n</link>
      <guid>https://dev.to/walsoup/roamshot-photo-side-quests-for-walks-with-open-models-running-on-the-phone-250n</guid>
      <description>&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;roamshot is an Android app for walks with something to look for. you pick a walk (a park, your neighborhood, a forest trail, or whatever you type in) and it hands you 3 to 5 photo side quests. each one has an objective and a difficulty. you go find something that fits, take the photo, and a small vision model checks whether it matches. if it misses you can retry or skip.&lt;/p&gt;

&lt;p&gt;completed photos go into a gallery of instant-photo frames. a quest is worth 10, 20 or 30 points depending on difficulty, plus 5 for getting it on the first try, and one verified quest a day keeps your streak alive.&lt;/p&gt;

&lt;p&gt;the point is that the phone is only there to give you a reason to look up. the quests point you at things in the world, and the answer is outside. there are no accounts, no backend, no social feed and no maps. it's for anyone who walks anyway and wants to pay a bit more attention.&lt;/p&gt;

&lt;p&gt;quests are not allowed to ask for photos of people or faces, trespassing, private property, roads or traffic, unsafe night activities, or purchases. night walks, yes. horror-movie decisions, no.&lt;/p&gt;

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

&lt;p&gt;no video demo.&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%2Fp53fkqkyrc94qhnnpphi.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%2Fp53fkqkyrc94qhnnpphi.png" alt="walk setup: pick a preset or type your own walk" width="720" height="1462"&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%2Flnkt6iw4alloe7wrrvl5.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%2Flnkt6iw4alloe7wrrvl5.png" alt="the quest board with generated side quests" width="720" height="1462"&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%2Fw84xe21sw2uc6z5uur49.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%2Fw84xe21sw2uc6z5uur49.png" alt="the capture viewfinder" width="720" height="1462"&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%2Fyjazxroq83x5cueau6nf.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%2Fyjazxroq83x5cueau6nf.png" alt="the polaroid gallery" width="720" height="1462"&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%2Fl8snmje911u5769yc2s8.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%2Fl8snmje911u5769yc2s8.png" alt="stats: streak, points and the model downloads" width="720" height="1462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;i ran the whole thing on a low end budget phone, the worst one i have, on purpose. i also tested it offline, and the models downloaded and loaded on it, so the quests were generated by Qwen and not pulled from the built-in pool.&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/walsoup" rel="noopener noreferrer"&gt;
        walsoup
      &lt;/a&gt; / &lt;a href="https://github.com/walsoup/roamshot" rel="noopener noreferrer"&gt;
        roamshot
      &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;Polaroam 📸&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;An indie Android walking game with on-device AI side quests and instant photo checks.&lt;br&gt;
&lt;strong&gt;Crafted with ❤️ by &lt;a href="https://github.com/walsoup" rel="noopener noreferrer"&gt;@walsoup&lt;/a&gt;&lt;/strong&gt; • Version &lt;strong&gt;1.0.0&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Polaroam turns everyday walks into retro photo scavenger hunts. Pick a walk style (or type your own), get creative on-device AI side quests, snap what you find through a pixel viewfinder, and pin your developed Polaroids to your corkboard gallery.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📱 Screenshots&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;Walk Setup&lt;/th&gt;
&lt;th&gt;Quest Board&lt;/th&gt;
&lt;th&gt;Camera Viewfinder&lt;/th&gt;
&lt;th&gt;Polaroid Gallery&lt;/th&gt;
&lt;th&gt;Stats &amp;amp; AI Config&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/walsoup/roamshot/docs/screenshots/home.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwalsoup%2Froamshot%2FHEAD%2Fdocs%2Fscreenshots%2Fhome.png" width="180" alt="Walk Setup"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/walsoup/roamshot/docs/screenshots/quest_board.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwalsoup%2Froamshot%2FHEAD%2Fdocs%2Fscreenshots%2Fquest_board.png" width="180" alt="Quest Board"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/walsoup/roamshot/docs/screenshots/capture.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwalsoup%2Froamshot%2FHEAD%2Fdocs%2Fscreenshots%2Fcapture.png" width="180" alt="Capture Viewfinder"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/walsoup/roamshot/docs/screenshots/gallery.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwalsoup%2Froamshot%2FHEAD%2Fdocs%2Fscreenshots%2Fgallery.png" width="180" alt="Polaroid Gallery"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/walsoup/roamshot/docs/screenshots/stats.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwalsoup%2Froamshot%2FHEAD%2Fdocs%2Fscreenshots%2Fstats.png" width="180" alt="Stats &amp;amp; Credits"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;Pick presets or custom walks&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;AI-generated side quests&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Viewfinder with pixel reticle&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Corkboard with Polaroids&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Streak, score &amp;amp; &lt;a class="mentioned-user" href="https://dev.to/walsoup"&gt;@walsoup&lt;/a&gt; credits&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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;Curated &amp;amp; Custom Walks&lt;/strong&gt;: Choose from 7 themed presets (&lt;em&gt;Neighborhood, City park, Forest trail, Coastal walk, Rainy stroll, Mountain trail, Night walk&lt;/em&gt;) or type whatever walk you're taking.&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;On-Device AI Quests&lt;/strong&gt;: Generates 3–5 tailored photo objectives per walk with difficulty tiers (1–3 pips) 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/walsoup/roamshot" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Kotlin, Jetpack Compose, CameraX, Room, Hilt. the code lives in the repo under the package &lt;code&gt;app.polaroam&lt;/code&gt;, which is the name the app had before it was roamshot.&lt;/p&gt;

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

&lt;p&gt;every AI piece is an open model and runs on the phone.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;job&lt;/th&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;writing quests&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://huggingface.co/litert-community/Qwen3-0.6B" rel="noopener noreferrer"&gt;Qwen3-0.6B&lt;/a&gt; (Apache-2.0)&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://github.com/google-ai-edge/LiteRT-LM" rel="noopener noreferrer"&gt;LiteRT-LM&lt;/a&gt; (Apache-2.0)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;checking photos&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://huggingface.co/openai/clip-vit-base-patch32" rel="noopener noreferrer"&gt;CLIP ViT-B/32&lt;/a&gt; (MIT), int8 ONNX export&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://github.com/microsoft/onnxruntime" rel="noopener noreferrer"&gt;ONNX Runtime&lt;/a&gt; (MIT)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;quests.&lt;/strong&gt; Qwen3-0.6B gets a system prompt and a walk type and writes the quests as JSON. the output goes through a parser and a safety filter. if it fails, the app retries once, and if that fails too it falls back to a built-in pool of canned quests, so a walk never starts with an empty board. there's also a smaller option, SmolLM2-360M, if the phone struggles with Qwen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;photo check.&lt;/strong&gt; CLIP runs zero-shot. a script (&lt;code&gt;tools/clip/build_label_embeddings.py&lt;/code&gt;) precomputes a text embedding for every label the quests can use, plus a few distractors like person, car and food, so an off-target photo has somewhere to land. on the phone, only CLIP's image encoder runs. a photo counts as a match when the quest's target labels together reach 20% and beat every other single label. that second rule is what stops a sandwich passing as a mushroom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;models are not in the APK.&lt;/strong&gt; the Stats screen downloads both on Wi-Fi, about 700 MB with the default pair. the downloads are pinned to a specific Hugging Face commit and checked with sha256. until they're there, quests come from the built-in pool and photos can't be checked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;swapping models.&lt;/strong&gt; the generator and the verifier are two interfaces (&lt;code&gt;QuestGenerator&lt;/code&gt;, &lt;code&gt;PhotoVerifier&lt;/code&gt;), and the choice of implementation lives in one file, &lt;code&gt;di/AiModule.kt&lt;/code&gt;. you can point &lt;code&gt;local.properties&lt;/code&gt; at a different &lt;code&gt;.litertlm&lt;/code&gt; or ONNX file and rebuild. a different CLIP needs its own label embeddings.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;photos stay on the phone.&lt;/strong&gt; the thing being sent to a model is a picture of wherever you are. with CLIP running locally, nothing you photograph leaves the device.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;it works with no signal.&lt;/strong&gt; after the one-time download, a walk needs no connection, and i tested it offline. trails are where signal is bad.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;it costs nothing to run.&lt;/strong&gt; there's no API bill, so no backend, no accounts and no limit on how many quests anyone generates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could swap models.&lt;/strong&gt; the first plan was different (I looked at Gemma through LiteRT, which was slow to load on my phone, and at Moondream2). because the weights are open and the runtimes are open, trying Qwen3 and CLIP instead was a change to a config and a few classes, not a new vendor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;the tradeoff is honest: a 0.6B model writes plainer quests than a hosted one would, and CLIP zero-shot gets some photos wrong. that is the price of running on a phone, and for a "go look at a tree" app I think it's fine.&lt;/p&gt;

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