<?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: Abbey 🌠</title>
    <description>The latest articles on DEV Community by Abbey 🌠 (@abbeywillblog).</description>
    <link>https://dev.to/abbeywillblog</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%2F946425%2Fe13b4b80-5c38-4818-ad02-2e03ff805e9a.png</url>
      <title>DEV Community: Abbey 🌠</title>
      <link>https://dev.to/abbeywillblog</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abbeywillblog"/>
    <language>en</language>
    <item>
      <title>Ghost in the Repo: Resurrecting Abandoned Code with a Local Open Model</title>
      <dc:creator>Abbey 🌠</dc:creator>
      <pubDate>Sat, 31 Oct 2026 15:42:39 +0000</pubDate>
      <link>https://dev.to/abbeywillblog/readme-resurrection-2ool</link>
      <guid>https://dev.to/abbeywillblog/readme-resurrection-2ool</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;README Resurrection&lt;/strong&gt; is a command-line tool that raises abandoned repositories from the dead. Point it at a repo with no documentation and it writes a README, setup instructions, an architecture overview and a contributing guide, using a local open-weight model. Then it checks its own work and flags anything it couldn't verify.&lt;/p&gt;

&lt;p&gt;For the theme, I took "ghost in the machine" literally. An abandoned project is a ghost: the code is still there and still runs, but the person who understood it is gone. Documentation is how the living remember the dead, so I wanted a tool that goes through a forgotten repo and writes down what it was. Before it generates anything, it prints a "Resurrection report" that says whether the repo is alive, dormant or dead, and how much documentation it's missing.&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/AbbeyIT" rel="noopener noreferrer"&gt;
        AbbeyIT
      &lt;/a&gt; / &lt;a href="https://github.com/AbbeyIT/readme-resurrection" rel="noopener noreferrer"&gt;
        readme-resurrection
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A tool for generating README.md files for software repositories using various facts about the repository.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;&lt;strong&gt;The open stack:&lt;/strong&gt; &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; running &lt;strong&gt;Qwen2.5-coder:7b&lt;/strong&gt; locally, with a small Python CLI (typer, rich, httpx) around it. There are no API keys and no hosted models in the product. I developed it on a Windows laptop with &lt;strong&gt;no GPU&lt;/strong&gt;, so the model runs 100% on CPU.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The lesson that shaped the design:&lt;/strong&gt; a small model asked to "write a README" invents things. My first generated README had a Usage section with command-line arguments that don't exist. Its Architecture document claimed modules imported each other when they didn't. The model wasn't broken; my facts had gaps, and it filled them with plausible guesses.&lt;/p&gt;

&lt;p&gt;So the tool does as little as possible with the model:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Plain code collects the facts:&lt;/strong&gt; file tree, languages, dependencies, entry points, scripts, license type (detected from the license text), and the real Python import graph read with the &lt;code&gt;ast&lt;/code&gt; module.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model summarizes key files&lt;/strong&gt;, with results cached by content hash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model writes each document&lt;/strong&gt; from those facts only, with a list of &lt;em&gt;verified commands&lt;/em&gt; it's allowed to use and a rule to write &lt;code&gt;unknown&lt;/code&gt; rather than guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plain code verifies the output.&lt;/strong&gt; Every file path, command and "X imports Y" claim is checked against the repo, and anything that doesn't hold up goes into a &lt;code&gt;## Needs review&lt;/code&gt; section.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each time a document was wrong, the fix was never a cleverer prompt. It was a better fact, extracted by code: the CLI entry point from &lt;code&gt;pyproject.toml&lt;/code&gt;, the license type from the license text, the optional &lt;code&gt;[dev]&lt;/code&gt; dependencies, the import graph.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How the code got written:&lt;/strong&gt; &lt;br&gt;
I tried driving the build with opencode pointed at a local Ollama model, but on CPU it ran at about 0.3 tokens per second and the 7B model printed its tool call as plain text instead of executing it, so no files were created. I then built the project in small steps with a hosted AI assistant helping draft the code, and I ran, tested and committed each step myself. &lt;/p&gt;
&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;The people who most need this tool are working with code they can't upload. Legacy and proprietary repositories are exactly where documentation is missing, and exactly where sending the source to a closed API isn't an option. With an open-weight model running through Ollama:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The code never leaves the machine.&lt;/strong&gt; That's the difference between a tool you could use at work and one you couldn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works offline.&lt;/strong&gt; Once the model is pulled, no network is needed (except to clone a repo).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model is swappable.&lt;/strong&gt; &lt;code&gt;--model&lt;/code&gt; takes any Ollama model, and all model access is in one small file. When I found my 7B model was slow on CPU, switching to a smaller one was a flag, not a rewrite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing to run.&lt;/strong&gt; No keys, no per-token billing, so it's practical to re-run it on a whole folder of old repos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing is locked in.&lt;/strong&gt; There's no service that can change pricing, retire a model, or disappear. That seemed right for a tool whose whole point is rescuing things that were abandoned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open models also made the hard part easier to see. Because I could run the same small model locally and watch exactly where it went wrong, I learned that the answer was grounding it in facts, and the same approach would help with larger models too.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Spirit of It
&lt;/h2&gt;

&lt;p&gt;I pointed the tool at GitHub's oldest demo repository, &lt;code&gt;octocat/Hello-World&lt;/code&gt;, to see how it describes a ghost:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Condition      DEAD - last commit 2012-03-06, 14 years, 8 months (5,351 days) ago
README         stub (README, under 500 bytes)
SETUP          missing
ARCHITECTURE   missing
CONTRIBUTING   missing
Revival score  100/100  ##########
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is from my own repo:&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%2F26d57pc5x0i1krol4u02.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%2F26d57pc5x0i1krol4u02.png" alt=" " width="800" height="662"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Sloth Tidy: A Local AI That Cleans Your Messy Folders While You Nap</title>
      <dc:creator>Abbey 🌠</dc:creator>
      <pubDate>Sat, 24 Oct 2026 16:12:50 +0000</pubDate>
      <link>https://dev.to/abbeywillblog/sloth-tidy-a-local-ai-that-cleans-your-messy-folders-while-you-nap-34h3</link>
      <guid>https://dev.to/abbeywillblog/sloth-tidy-a-local-ai-that-cleans-your-messy-folders-while-you-nap-34h3</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 Tidy is a command-line tool that cleans up a messy folder (think Downloads) using an open-weight model running on my own machine.&lt;/p&gt;

&lt;p&gt;You point it at a folder. For each file it reads a short snippet, then proposes a category, a clean filename, and a destination: &lt;code&gt;scan0012.pdf&lt;/code&gt; becomes &lt;code&gt;Invoices/2026/2026-10-31_meralco-electricity-bill.pdf&lt;/code&gt;. Nothing moves until you review a dry-run plan and apply it, and every move can be undone with one command. There's also a watch mode that files new arrivals in the background.&lt;/p&gt;

&lt;p&gt;It's for anyone who has a folder full of &lt;code&gt;scan0012.pdf&lt;/code&gt;, &lt;code&gt;Document (3).docx&lt;/code&gt;, and &lt;code&gt;Screenshot 2026-10-03.png&lt;/code&gt; and keeps putting off the cleanup. The sloth move is to run it once and walk away.&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/AbbeyIT" rel="noopener noreferrer"&gt;
        AbbeyIT
      &lt;/a&gt; / &lt;a href="https://github.com/AbbeyIT/sloth-tidy" rel="noopener noreferrer"&gt;
        sloth-tidy
      &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;Sloth Tidy&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Point it at a messy folder; a local open-weight model proposes where everything belongs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why local and open&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Sloth Tidy sends readable file snippets to Ollama on your machine by default. After you pull a model, it can run without internet access, hosted model APIs, or API keys; file contents stay on your machine. Choose another Ollama model with &lt;code&gt;SLOTH_MODEL&lt;/code&gt;, and steer its decisions with &lt;code&gt;rules.yaml&lt;/code&gt;. A remote Ollama server is possible only when you explicitly pass &lt;code&gt;--allow-remote&lt;/code&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements and setup&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 20 or newer&lt;/li&gt;
&lt;li&gt;Ollama installed and running&lt;/li&gt;
&lt;li&gt;A pulled model; the default is &lt;code&gt;qwen2.5:7b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Model weights are not included and are subject to their own licenses.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;ollama pull qwen2.5:7b
npm install
npm run build
npm &lt;span class="pl-c1"&gt;test&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick start with the demo&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Generate the 30-file demo, copy it, and plan against the copy. The plan is written beside the copy so it is not…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/AbbeyIT/sloth-tidy" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;MIT licensed. TypeScript, Node 20+, and Ollama.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;The open parts at runtime:&lt;/strong&gt; &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; serves &lt;code&gt;qwen2.5:7b&lt;/code&gt; locally. The tool talks to it over plain HTTP on localhost, with no API keys and no hosted services. The model name is one environment variable, &lt;code&gt;SLOTH_MODEL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I built the project:&lt;/strong&gt; I wrote a &lt;code&gt;SPEC.md&lt;/code&gt; and built it in seven milestones with OpenAI Codex, committing after each one. The runtime doesn't depend on Codex, only the building did. Dependencies are small: &lt;code&gt;commander&lt;/code&gt;, &lt;code&gt;zod&lt;/code&gt;, &lt;code&gt;pdf-parse&lt;/code&gt;, &lt;code&gt;mammoth&lt;/code&gt;, and &lt;code&gt;vitest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The main lesson is that a small local model needs a tight leash.&lt;/strong&gt; My first version asked the model for a folder and a filename, and the results were bad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reasons came back in Chinese, because Qwen drifted languages.&lt;/li&gt;
&lt;li&gt;Folder names were garbage, like &lt;code&gt;Invoices/2026-10-20-09-02-34-Meralco_Electricity_Billpdfgz-invoices-2026-10-20&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Timestamps were invented.&lt;/li&gt;
&lt;li&gt;Files kept their original names.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I changed the design so the model decides as little as possible:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The model &lt;strong&gt;picks a category from a fixed list&lt;/strong&gt; (enforced with a JSON schema) and writes a 2 to 6 word description. It never writes a path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code builds the folder and filename&lt;/strong&gt; and keeps the original extension.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dates must be verified.&lt;/strong&gt; A date the model returns has to actually appear in the file's text, and the checker understands things like "01–31 October 2026". Otherwise the file's modified date is used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output is validated.&lt;/strong&gt; Non-English text, invalid categories, and bad JSON are rejected and retried once, then the file is left in place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Files with no readable content&lt;/strong&gt; (images, installers) never reach the model. They're filed by extension. On my demo folder that was 10 of 30 files, so they cost nothing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Safety is designed in: dry-run by default, never overwrite or delete, destinations can't escape the root folder, files that changed since planning are skipped, and every batch goes in an undo log. Watch mode only moves files with an explicit &lt;code&gt;--apply&lt;/code&gt; flag and only above a confidence threshold. Anything it isn't sure about waits in a pending plan.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;rules.yaml&lt;/code&gt; file steers it without touching code: allowed folders, files to never touch, and overrides like "&lt;code&gt;worksheet*.docx&lt;/code&gt; always goes to School".&lt;/p&gt;

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

&lt;p&gt;A Downloads folder is some of the most personal data on a computer: invoices, school forms, lease summaries, job applications. Sending a stranger's server the first lines of every file to sort them is a hard sell. With a local open-weight model, the file contents never leave the machine, and it works offline once the model is pulled.&lt;/p&gt;

&lt;p&gt;Three more things open made possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost.&lt;/strong&gt; My plan run takes several minutes, which is fine when the model is free. With a metered API, "run it on every new file in the background" becomes a bill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappability.&lt;/strong&gt; One environment variable changes the model, and I could compare two models on the same folder with no new accounts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control.&lt;/strong&gt; Because the model runs locally with schema-enforced output, I could build guardrails around it and test them with a mocked model, 71 tests in total.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be fair to closed models: a larger hosted model would probably be more consistent on borderline files. In my runs, the lease summary landed in &lt;code&gt;Personal&lt;/code&gt; once and in &lt;code&gt;Work&lt;/code&gt; another time, even at temperature 0. That's why &lt;code&gt;rules.yaml&lt;/code&gt; overrides exist. For this particular job, I'd take a slightly less consistent model that never sees my files.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Payload Doctor: a private, offline AI that explains failing integration payloads</title>
      <dc:creator>Abbey 🌠</dc:creator>
      <pubDate>Mon, 19 Oct 2026 10:07:59 +0000</pubDate>
      <link>https://dev.to/abbeywillblog/payload-doctor-a-private-offline-ai-that-explains-failing-integration-payloads-1lfg</link>
      <guid>https://dev.to/abbeywillblog/payload-doctor-a-private-offline-ai-that-explains-failing-integration-payloads-1lfg</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;Payload Doctor&lt;/strong&gt; is a small tool for integration developers. You paste a failing JSON or XML payload and the error it produced, and a local AI model explains what went wrong and suggests a fix.&lt;/p&gt;

&lt;p&gt;I work with enterprise integrations day to day, and one of the most common time sinks is staring at a rejected payload: a wrong date format, a missing field, a namespace mismatch, an expired token. The obvious shortcut is pasting it into a cloud chatbot, but integration payloads contain business data (customer names, emails, order details, credentials), and that data usually isn't yours to send to a third party.&lt;/p&gt;

&lt;p&gt;The people who would pay for this are freelance integration consultants and small dev shops that work with client data and can't, or won't, paste it into a cloud AI. Payload Doctor gives them the speed of an AI assistant without the data leaving their laptop.&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/AbbeyIT" rel="noopener noreferrer"&gt;
        AbbeyIT
      &lt;/a&gt; / &lt;a href="https://github.com/AbbeyIT/payload-doctor" rel="noopener noreferrer"&gt;
        payload-doctor
      &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;Payload Doctor&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A local, private assistant for integration developers. Paste a failing JSON/XML payload and its error, and an open-weight model running on your own machine explains what went wrong and how to fix it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Runs on your laptop through &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt;. No cloud API, no per-request cost, works offline.&lt;/li&gt;
&lt;li&gt;Emails, tokens, IPs, and long IDs are masked &lt;strong&gt;in code&lt;/strong&gt; before the model sees anything. The UI shows exactly what was sent.&lt;/li&gt;
&lt;li&gt;The server binds to &lt;code&gt;127.0.0.1&lt;/code&gt; only.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 1. Install Ollama (https://ollama.com), then pull a model&lt;/span&gt;
ollama pull qwen3.5:4b      &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or a smaller one: llama3.2:3b&lt;/span&gt;

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 2. Run the app&lt;/span&gt;
npm install
npm start                            &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; http://127.0.0.1:3000&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Options (environment variables): &lt;code&gt;MODEL&lt;/code&gt; (default &lt;code&gt;qwen3.5:4b&lt;/code&gt;), &lt;code&gt;PORT&lt;/code&gt; (default &lt;code&gt;3000&lt;/code&gt;), &lt;code&gt;OLLAMA_HOST&lt;/code&gt; (default &lt;code&gt;http://127.0.0.1:11434&lt;/code&gt;).&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;src/redact.ts&lt;/code&gt; masks secrets and personal data, using the same placeholder for the same value (&lt;code&gt;[EMAIL_1]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/prompt.ts&lt;/code&gt; builds the prompt and adds…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/AbbeyIT/payload-doctor" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; &lt;code&gt;qwen3.5:4b&lt;/code&gt;, an open-weight model, running locally through &lt;strong&gt;Ollama&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App:&lt;/strong&gt; Node.js and TypeScript with Express, and a single plain HTML page for the UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No cloud calls:&lt;/strong&gt; the server talks only to the local Ollama API and binds to &lt;code&gt;127.0.0.1&lt;/code&gt;, so it isn't reachable from other machines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model is only part of what makes it work. Most of the reliability comes from the code around it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Redaction before the model.&lt;/strong&gt; Emails, tokens, JWTs, IP addresses, phone numbers, and long opaque IDs are masked in code before the model sees anything. The same value always gets the same placeholder (&lt;code&gt;[EMAIL_1]&lt;/code&gt;), so the model can still reason about it. The UI shows exactly what was sent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A deterministic parser check.&lt;/strong&gt; Small models are unreliable at spotting a missing comma. So the code runs &lt;code&gt;JSON.parse&lt;/code&gt; first and tells the model whether the payload is valid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured, validated output.&lt;/strong&gt; The model replies in JSON, which I validate with zod. If the reply is unusable, the app retries once with the validation error.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A small eval script.&lt;/strong&gt; &lt;code&gt;npm run eval&lt;/code&gt; runs a file of test cases through the model and reports PASS or FAIL, so I can change the prompt or the model and see what happens.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Testing it
&lt;/h3&gt;

&lt;p&gt;I wrote 10 test cases for problems I see often in integration work, all with fake data: a wrong date format with a missing required field, a trailing comma in JSON, a SOAP namespace mismatch, an expired auth token, a string sent where an integer was expected, a payload that's too large, a missing Content-Type header, an upstream gateway timeout, a rate limit, and malformed URL-encoded form data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Results:&lt;/strong&gt; 10 of 10 passed on &lt;code&gt;qwen3.5:4b&lt;/code&gt;, each on the first attempt with no retry needed. Answers took 26 to 42 seconds each on my laptop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where the small model struggled:&lt;/strong&gt; the answers were right from the start, but my first run was far too slow. The gateway timeout case took 179 seconds, the expired token case took 107, and the SOAP namespace case hit my 180-second timeout and failed. The model was spending most of that time on hidden "thinking" before it replied. Because the model is open and runs locally, I could change that directly: I turned off its thinking mode and raised the request timeout. The same cases then ran in about 30 seconds, and the SOAP case passed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known limits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The eval is a keyword check. It confirms that the answer mentions the right field or concept, not that every word of the fix is correct.&lt;/li&gt;
&lt;li&gt;Redaction is pattern-based, so it won't catch things like names or account numbers.&lt;/li&gt;
&lt;li&gt;Treat the answer as a second opinion, not a verdict.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Because of what this tool is&lt;/p&gt;

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