What I Built
Every freelancer knows this email:
Loving the designs so far! A few small things... could we also add online ordering? And a Spanish version? Oh, and could you write the About page copy?
Each line sounds small. Together they are a second project, and saying "that's extra" without sounding difficult is the hard part. Most of us either do the work for free or spend an hour re-reading the contract and writing a careful reply.
Scope Creep Guard does that hour for you. You paste two things:
- π The scope you agreed (contract, proposal or SOW)
- βοΈ The client's new email
It gives you back:
- β / β / β A verdict for every request: in scope, out of scope or unclear
- π The exact line of your contract that backs each verdict
- β±οΈ An hour estimate for the extra work, priced at your hourly rate
- π¨ A friendly, ready-to-send reply that confirms the in-scope work and lists the rest as a priced change order
Who would pay for it: freelance designers, developers, copywriters and small agencies. Anyone who sends proposals and gets "quick favour" emails. Unbilled scope creep easily costs a freelancer a few hundred dollars a month, so a one-time price of around $19 for a packaged desktop version pays for itself the first time it catches one extra page. The core stays open source and free to run.
Demo
Here is a real run on the sample project in the repo: a 5-page bakery website, fixed price, two rounds of revisions, with copywriting, e-commerce and translations explicitly excluded. The client email asks for five things.
| Request | Verdict | Contract line it cites | Estimate |
|---|---|---|---|
| Bigger menu text on mobile | β In scope (a revision) | - | - |
| Pre-order birthday cakes with a deposit | β Out of scope | "Online ordering, payments or e-commerce of any kind." | ~4 h |
| Spanish version of the site | β Out of scope | "Translations into other languages." | ~16 h |
| A page for the second shop | β Out of scope (6th page) | - | ~4 h |
| Write the "Our Story" paragraph | β Out of scope | "Copywriting and photography (client supplies all text and images)." | ~8 h |
At $60/h that is USD 1,920 of work that would otherwise have been done for free. The drafted reply:
Hi Maria,
Great to hear you're loving the designs! We'll definitely implement the changes
for the menu text on mobile. However, adding the pre-ordering functionality, the
Spanish translation, the additional shop page, and the 'Our Story' paragraph are
outside the original scope of this project. These can be added as a change order.
- pre-order birthday cakes on the site: ~4 h = USD 240.00
- Spanish version of the whole site: ~16 h = USD 960.00
- add a page for that shop too: ~4 h = USD 240.00
- write a short 'Our Story' paragraph: ~8 h = USD 480.00
Estimated total: USD 1,920.00
Best,
Code
SrilalS
/
scope-creep-guard
Local-first scope creep checker for freelancers: Gemma via Ollama flags out-of-scope client requests and drafts a priced change order.
π‘οΈ Scope Creep Guard
Paste the scope you agreed with a client and their latest email. Scope Creep Guard flags which requests are in scope, out of scope or unclear, quotes the line of your contract that backs each call, estimates the extra hours, and drafts a polite reply with a priced change order.
Everything runs on your own machine with an open-weight model (Gemma via Ollama). Your contracts and client emails never leave your laptop.
Quick start
-
Install Ollama and pull Gemma:
ollama pull gemma3:4b
-
Start the app (Python 3.10+, no extra packages needed):
python server.py
-
Open http://localhost:8000, click Load sample, then Check for scope creep.
Configuration
| Variable | Default | Purpose |
|---|---|---|
SCG_MODEL |
gemma3:4b |
Any Ollama model, for example gemma3:12b for better judgement |
OLLAMA_URL |
http://127.0.0.1:11434 |
Where Ollama is listening |
PORT |
8000 |
Web server port |
HOST |
127.0.0.1 |
Bind address (local only by default) |
How it works
-
scope_guard.pysends theβ¦
Three files do the work: scope_guard.py (prompt, model call and pricing), server.py (a tiny web server) and static/index.html (the whole UI). No dependencies beyond Python and Ollama.
How I Built It
Stack: Gemma 3 4B running locally through Ollama, a Python standard-library web server, and one HTML page.
browser ββPOST /api/analyzeβββΆ server.py ββ/api/chat + JSON schemaβββΆ Ollama (gemma3:4b)
β β
ββββββββ verdicts + hour estimates βββββββ
βΌ
Python: price, build change order,
write summary, fill reply template
A few decisions made the difference with a small model:
1. Structured output, not "please reply in JSON". Ollama accepts a JSON schema in the format field and constrains generation to it. Gemma has to return a list of items with request, verdict (an enum of the three values), reason, scope_quote and est_hours. I never had to parse broken JSON.
2. The model never does math. My first version let the model write the prices into the email. Small models are bad at arithmetic, and a change order with a wrong total is worse than none. Now Gemma only classifies and estimates hours. Python multiplies by the rate, builds the list and drops it into the email where the model left a {{CHANGE_ORDER}} token.
3. Don't trust the model to count either. In one early run the summary said "three new requests" right above a list of five. The summary line is now computed from the verdicts ("4 of 5 requests go beyond the agreed scope").
4. Teach it what a revision is. On the first run Gemma marked "make the menu text bigger" as out of scope. Technically it was not listed, but any freelancer would call it a revision, and the contract includes two rounds. A short rule in the prompt fixed it: small changes to work that is already in scope are revisions, and included revisions make them in scope. It also learned that "add another page" to a 5-page contract is extra quantity.
5. Clean up after the model. Gemma sometimes put the change-order token mid-sentence with a full stop after it. Rather than fight it with more prompt, a few lines of Python always give the table its own paragraph. These rules are covered by unit tests that run without a model.
Speed, honestly: my laptop has no usable GPU, so ollama ps shows the model at 100% CPU (2.9 GB loaded). One full check of the sample takes about 1 minute 45 seconds. That's slow for a chat app but fine for this job: you paste the email, go make a coffee, and come back to a reply you would have spent an hour on. On a machine with a supported GPU, Ollama offloads the model and it should be much faster (I haven't measured that yet).
Why Does Open Innovation Matter?
Because the input is a contract. The two things this tool reads are the most confidential documents a freelancer has: a signed agreement (often under NDA) and a client's private email. Confidentiality clauses often limit sharing client material with third parties, and pasting it into someone else's cloud is exactly that. With an open-weight model on my own machine, nothing leaves the laptop. It even works offline, on a train, with the Wi-Fi off. That isn't a nice-to-have for this product; it's the reason a cautious freelancer would trust it with their contracts.
Because it makes the business model work. A hosted API charges per call, forever, so a hosted version would need a subscription. Running Gemma locally makes every check free after the download. That's what makes a cheap, pay-once tool for solo freelancers possible.
Because I can swap the brain. SCG_MODEL=gemma3:12b python server.py and it uses a bigger Gemma for better judgement, or any other Ollama model. No vendor can deprecate the model under me or change its behaviour overnight, and a future version could be fine-tuned on real scope disputes.
Where closed would have been better: speed. A hosted frontier model would answer in seconds and probably give tighter hour estimates. For a tool whose whole job is guarding private documents, I'll trade two minutes for keeping them on my laptop.
My Agent Session
I built this with Claude Code as my pair programmer: planning, writing the server and UI, running Gemma end to end and fixing the quality issues described above.## What I Built
Every freelancer knows this email:
Loving the designs so far! A few small things... could we also add online ordering? And a Spanish version? Oh, and could you write the About page copy?
Each line sounds small. Together they are a second project, and saying "that's extra" without sounding difficult is the hard part. Most of us either do the work for free or spend an hour re-reading the contract and writing a careful reply.
Scope Creep Guard does that hour for you. You paste two things:
- π The scope you agreed (contract, proposal or SOW)
- βοΈ The client's new email
It gives you back:
- β / β / β A verdict for every request: in scope, out of scope or unclear
- π The exact line of your contract that backs each verdict
- β±οΈ An hour estimate for the extra work, priced at your hourly rate
- π¨ A friendly, ready-to-send reply that confirms the in-scope work and lists the rest as a priced change order
Who would pay for it: freelance designers, developers, copywriters and small agencies. Anyone who sends proposals and gets "quick favour" emails. Unbilled scope creep easily costs a freelancer a few hundred dollars a month, so a one-time price of around $19 for a packaged desktop version pays for itself the first time it catches one extra page. The core stays open source and free to run.
Demo
Here is a real run on the sample project in the repo: a 5-page bakery website, fixed price, two rounds of revisions, with copywriting, e-commerce and translations explicitly excluded. The client email asks for five things.
| Request | Verdict | Contract line it cites | Estimate |
|---|---|---|---|
| Bigger menu text on mobile | β In scope (a revision) | - | - |
| Pre-order birthday cakes with a deposit | β Out of scope | "Online ordering, payments or e-commerce of any kind." | ~4 h |
| Spanish version of the site | β Out of scope | "Translations into other languages." | ~16 h |
| A page for the second shop | β Out of scope (6th page) | - | ~4 h |
| Write the "Our Story" paragraph | β Out of scope | "Copywriting and photography (client supplies all text and images)." | ~8 h |
At $60/h that is USD 1,920 of work that would otherwise have been done for free. The drafted reply:
Hi Maria,
Great to hear you're loving the designs! We'll definitely implement the changes
for the menu text on mobile. However, adding the pre-ordering functionality, the
Spanish translation, the additional shop page, and the 'Our Story' paragraph are
outside the original scope of this project. These can be added as a change order.
- pre-order birthday cakes on the site: ~4 h = USD 240.00
- Spanish version of the whole site: ~16 h = USD 960.00
- add a page for that shop too: ~4 h = USD 240.00
- write a short 'Our Story' paragraph: ~8 h = USD 480.00
Estimated total: USD 1,920.00
Best,
Code
SrilalS
/
scope-creep-guard
Local-first scope creep checker for freelancers: Gemma via Ollama flags out-of-scope client requests and drafts a priced change order.
π‘οΈ Scope Creep Guard
Paste the scope you agreed with a client and their latest email. Scope Creep Guard flags which requests are in scope, out of scope or unclear, quotes the line of your contract that backs each call, estimates the extra hours, and drafts a polite reply with a priced change order.
Everything runs on your own machine with an open-weight model (Gemma via Ollama). Your contracts and client emails never leave your laptop.
Quick start
-
Install Ollama and pull Gemma:
ollama pull gemma3:4b
-
Start the app (Python 3.10+, no extra packages needed):
python server.py
-
Open http://localhost:8000, click Load sample, then Check for scope creep.
Configuration
| Variable | Default | Purpose |
|---|---|---|
SCG_MODEL |
gemma3:4b |
Any Ollama model, for example gemma3:12b for better judgement |
OLLAMA_URL |
http://127.0.0.1:11434 |
Where Ollama is listening |
PORT |
8000 |
Web server port |
HOST |
127.0.0.1 |
Bind address (local only by default) |
How it works
-
scope_guard.pysends theβ¦
Three files do the work: scope_guard.py (prompt, model call and pricing), server.py (a tiny web server) and static/index.html (the whole UI). No dependencies beyond Python and Ollama.
How I Built It
Stack: Gemma 3 4B running locally through Ollama, a Python standard-library web server, and one HTML page.
browser ββPOST /api/analyzeβββΆ server.py ββ/api/chat + JSON schemaβββΆ Ollama (gemma3:4b)
β β
ββββββββ verdicts + hour estimates βββββββ
βΌ
Python: price, build change order,
write summary, fill reply template
A few decisions made the difference with a small model:
1. Structured output, not "please reply in JSON". Ollama accepts a JSON schema in the format field and constrains generation to it. Gemma has to return a list of items with request, verdict (an enum of the three values), reason, scope_quote and est_hours. I never had to parse broken JSON.
2. The model never does math. My first version let the model write the prices into the email. Small models are bad at arithmetic, and a change order with a wrong total is worse than none. Now Gemma only classifies and estimates hours. Python multiplies by the rate, builds the list and drops it into the email where the model left a {{CHANGE_ORDER}} token.
3. Don't trust the model to count either. In one early run the summary said "three new requests" right above a list of five. The summary line is now computed from the verdicts ("4 of 5 requests go beyond the agreed scope").
4. Teach it what a revision is. On the first run Gemma marked "make the menu text bigger" as out of scope. Technically it was not listed, but any freelancer would call it a revision, and the contract includes two rounds. A short rule in the prompt fixed it: small changes to work that is already in scope are revisions, and included revisions make them in scope. It also learned that "add another page" to a 5-page contract is extra quantity.
5. Clean up after the model. Gemma sometimes put the change-order token mid-sentence with a full stop after it. Rather than fight it with more prompt, a few lines of Python always give the table its own paragraph. These rules are covered by unit tests that run without a model.
Speed, honestly: my laptop has no usable GPU, so ollama ps shows the model at 100% CPU (2.9 GB loaded). One full check of the sample takes about 1 minute 45 seconds. That's slow for a chat app but fine for this job: you paste the email, go make a coffee, and come back to a reply you would have spent an hour on. On a machine with a supported GPU, Ollama offloads the model and it should be much faster (I haven't measured that yet).
Why Does Open Innovation Matter?
Because the input is a contract. The two things this tool reads are the most confidential documents a freelancer has: a signed agreement (often under NDA) and a client's private email. Confidentiality clauses often limit sharing client material with third parties, and pasting it into someone else's cloud is exactly that. With an open-weight model on my own machine, nothing leaves the laptop. It even works offline, on a train, with the Wi-Fi off. That isn't a nice-to-have for this product; it's the reason a cautious freelancer would trust it with their contracts.
Because it makes the business model work. A hosted API charges per call, forever, so a hosted version would need a subscription. Running Gemma locally makes every check free after the download. That's what makes a cheap, pay-once tool for solo freelancers possible.
Because I can swap the brain. SCG_MODEL=gemma3:12b python server.py and it uses a bigger Gemma for better judgement, or any other Ollama model. No vendor can deprecate the model under me or change its behaviour overnight, and a future version could be fine-tuned on real scope disputes.
Where closed would have been better: speed. A hosted frontier model would answer in seconds and probably give tighter hour estimates. For a tool whose whole job is guarding private documents, I'll trade two minutes for keeping them on my laptop.
My Agent Session
I built this with Claude Code as my pair programmer: planning, writing the server and UI, running Gemma end to end and fixing the quality issues described above.
Prize Categories
- Best Use of Gemma: Gemma 3 4B, running fully locally through Ollama, is the core of the product.
Top comments (0)