<?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: zoizero86-beep</title>
    <description>The latest articles on DEV Community by zoizero86-beep (@zoizero86beep).</description>
    <link>https://dev.to/zoizero86beep</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%2F4192526%2Ff364aed9-f24e-447e-9661-82f54a2676a7.png</url>
      <title>DEV Community: zoizero86-beep</title>
      <link>https://dev.to/zoizero86beep</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zoizero86beep"/>
    <language>en</language>
    <item>
      <title>ScopeGuard: a scope-creep checker for freelancers that never uploads the client's text</title>
      <dc:creator>zoizero86-beep</dc:creator>
      <pubDate>Sun, 18 Oct 2026 17:07:40 +0000</pubDate>
      <link>https://dev.to/zoizero86beep/scopeguard-a-scope-creep-checker-for-freelancers-that-never-uploads-the-clients-text-3ak4</link>
      <guid>https://dev.to/zoizero86beep/scopeguard-a-scope-creep-checker-for-freelancers-that-never-uploads-the-clients-text-3ak4</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;ScopeGuard&lt;/strong&gt; is one static page that answers a question every freelancer on a fixed fee has asked themselves: &lt;em&gt;which lines in this client message did I actually agree to?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You paste the scope you signed - the brief, the proposal, the SOW - and the message that just landed in your inbox. The page splits both into sentences, embeds them locally, and prints, line by line, how close each new ask is to something you promised. Anything that does not match gets flagged with its similarity score and the closest line from your scope. Below that it drafts a reply that separates "that was in scope, I'll pick it up" from "that's new work, here's a change order".&lt;/p&gt;

&lt;p&gt;Who would pay for it: freelancers and two-person studios on fixed-fee projects - the people whose margin disappears into "while you're in there, can you also...". The version I would charge for is this page plus per-client project files, a change-order PDF export, and a read-only link the client can open.&lt;/p&gt;

&lt;p&gt;The local-first part is not ideology, it is the actual blocker. A lot of this text is under NDA, or it is a client's unreleased roadmap. Those people cannot paste it into a cloud tool, and asking them to is how you lose the sale. A 23 MB model that runs in the tab is the difference between "I can use this at work" and "I can't".&lt;/p&gt;

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

&lt;p&gt;Live, no signup, nothing to install: &lt;strong&gt;&lt;a href="https://zoizero86-beep.github.io/scopeguard/" rel="noopener noreferrer"&gt;https://zoizero86-beep.github.io/scopeguard/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;em&gt;Load a sample&lt;/em&gt; and then &lt;em&gt;Check this message&lt;/em&gt;. Short version of what happens on the sample: of the 4 sentences in the client message, 3 fall below the 0.45 threshold, the mean best-match similarity is 0.345, and the sentence that does match lands at 0.478 against "Rewrite the onboarding copy on three screens". The reply draft then lists the three flagged lines as new work.&lt;/p&gt;

&lt;p&gt;The first run downloads about 23 MB of model once. After that it is served from the browser cache, and you can pull the network cable and it still works.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/zoizero86-beep/scopeguard" rel="noopener noreferrer"&gt;https://github.com/zoizero86-beep/scopeguard&lt;/a&gt;&lt;/strong&gt; - MIT, one HTML file, no build step, no dependencies to install.&lt;/p&gt;

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

&lt;p&gt;The whole thing is one &lt;code&gt;index.html&lt;/code&gt;. There is no backend, no account, no analytics, and no API key to leak.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/huggingface/transformers.js" rel="noopener noreferrer"&gt;transformers.js&lt;/a&gt;&lt;/strong&gt; (Apache-2.0) loaded straight from a CDN, running &lt;strong&gt;onnxruntime-web&lt;/strong&gt; with WASM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-weight model: &lt;a href="https://huggingface.co/Xenova/all-MiniLM-L6-v2" rel="noopener noreferrer"&gt;Xenova/all-MiniLM-L6-v2&lt;/a&gt;&lt;/strong&gt; (Apache-2.0), loaded as &lt;code&gt;dtype: 'q8'&lt;/code&gt; - about 23 MB - through &lt;code&gt;pipeline('feature-extraction', ...)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Embeddings are mean-pooled and L2-normalised in the pipeline, so similarity is a plain dot product, which is why scoring 40 sentences stays instant.&lt;/li&gt;
&lt;li&gt;Sentence splitting is a small regex pass that drops lines shorter than four words, because four-word fragments produce noisy matches.&lt;/li&gt;
&lt;li&gt;I set &lt;code&gt;env.backends.onnx.wasm.numThreads = 1&lt;/code&gt; so the page does not depend on &lt;code&gt;SharedArrayBuffer&lt;/code&gt; and therefore does not need COOP/COEP headers. That matters on GitHub Pages, where I cannot set response headers. One thread is slower and completely fine at this size.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What the model is doing here is narrow and worth being precise about: it scores topical relatedness between your scope and the new message. It is not reading intent, and it does not know what a contract is.&lt;/p&gt;

&lt;p&gt;The one thing I deliberately did &lt;strong&gt;not&lt;/strong&gt; put through a model is the reply. Asking a small text generator to write a client email would produce something confidently wrong about money. So the draft is a fixed template with your flagged lines dropped in, and the page says that in as many words.&lt;/p&gt;

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

&lt;p&gt;Three things that a closed API could not have given this project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The privacy claim is checkable.&lt;/strong&gt; "Your client's text never leaves the tab" is a statement I can prove - open the network panel after the model loads and watch it stay silent. With a hosted API, the same sentence would be marketing, not a fact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cost curve is flat.&lt;/strong&gt; This is meant to be used maybe forty times a month by one person. Zero marginal cost per check means the free tier can be genuinely free, and the paid tier can sell features instead of rationing tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model is a swappable part.&lt;/strong&gt; It is an ONNX sentence encoder. If a better small open-weight encoder appears, or someone needs a Chinese or German one, the swap is a string in one file. Nobody has to wait for a vendor to support a language, and nothing about the app depends on someone else's pricing page.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Not yet. I finished this during the entry period and have not put it in front of a paying freelancer, so there is no honest "they paid" story to tell here. What I can say is the obvious next step: three freelancers I know work on fixed fees, and the sample in the repo is built from a brief close enough to theirs that it should be an easy conversation.&lt;/p&gt;

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