This is my submission for the Hacktoberfest Open-Source AI Challenge: Week 3, "Slow and Steady".
What I built
Every to-do list has the same flaw: it only grows. Adding a task is free. Removing one needs a decision, and deciding is the part nobody does on purpose.
The Won't-Do List is an anti-to-do list. You paste everything you meant to get to (bullets, numbers, checkboxes, whatever your notes app spits out) and a small open-weight model, running on your own computer, sorts every task into one of four piles:
- Do now: ignoring it costs you soon, or it takes under ten minutes.
- Do later: it matters, but nothing breaks this week.
- Let it expire: nothing bad happens if it never gets done.
- Not my problem: it belongs to someone else, or you are waiting on them.
Every card says why, and, the part I care about most, says in one honest sentence what actually happens if you ignore it. The tasks you put down come back a week later for a single question: did letting go cost you anything? Your answers become examples the model sees next time.
The effort it saves is the effort you never spend. At the top of every sorted list the app tells you how many minutes you were just handed back.
Demo
Try it yourself. There is nothing to pip install; it is plain Python and plain JavaScript:
ollama pull gemma3:4b # or any instruct model of about 3B parameters or more
python3 -m wontdo # then open http://127.0.0.1:8742
No model running? The app still opens and sorts with a few keyword rules. They are not AI, and every list they make says so.
The lazy payoff
I ran it on my own list of 9 tasks with gemma3:4b on Windows 11:
| Tasks pasted | [9] |
| Put down (let it expire, not my problem) | [3] |
| Minutes handed back | [about 1 h 40 min] |
| Time for the model to sort the list | [300 seconds] |
| Verdicts I disagreed with | [1 of 9] |
The minutes are the model's own rough estimates, rounded to five, ten, fifteen minutes and so on. They are a nudge, not a stopwatch.
Why open innovation matters here
A task list is the most candid document you own. It holds the rent you are late on, the appointment you keep postponing, the name of the person you are avoiding. Sent to a hosted model, that list becomes a request body on a server I do not control. Run through an open-weight model on my own machine, it stays inside one process on one computer. The app listens on 127.0.0.1 only, it loads its own fonts, and a browser test records every request the page makes while you sort a list and fails if any of them leaves the machine.
It works on a plane. No account, no key, no quota, no connection.
The model is a setting, not a dependency. The app talks to Ollama, llama.cpp's llama-server, LM Studio or any OpenAI-compatible server. Swap one model for another and nothing else changes; the Test connection button tells you in about ten seconds whether the new one behaves. Because those protocols are open and simple, I could also test the whole pipeline against scripted stand-in servers that misbehave on purpose: invalid JSON, slow replies, dropped connections, a reasoning model that thinks out loud.
Nothing is metered. Sorting a list twice with two different models, to see who you trust, costs a little electricity.
Teaching it stays private. The check-in answers and the tasks you move by hand become up to six short examples in the next prompt. That trick works with any model. What open weights change is that those examples are the most personal data you have, and they never leave your disk.
Where a closed model would have been better. A large hosted model would almost certainly judge ambiguous tasks better than a 4B model on a laptop. A small model will sometimes tell you to ignore your tax return. So I did not try to make the model perfect. I built around it.
How I built it
The model proposes, plain rules veto. Seven regex tripwires (money, official paperwork, health, safety, booked commitments, people who matter, someone you answer to) plus your own never-skip words watch every task. If the model says "let it expire" and a tripwire fires, the task moves to Do later and the card says why. A second rule says the model cannot rate something medium or high risk and also skip it. Only you can overrule the net, with the Move to⦠menu. The rules lean towards false alarms on purpose: a false alarm costs one extra item on your list, and a missed one costs a late fee.
Dates are worked out by code. "by Friday" becomes [due in 6 days] before the model sees it, because small models are poor at calendar arithmetic.
Consequence before verdict. The output schema asks for if_ignored and risk before bucket, so the model has to write what happens if you ignore the task before it chooses a pile. I picked that order so the verdict has to agree with the sentence the model has just written. I did not run a controlled comparison, so treat it as a design choice, not a result.
Small models are messy, so the client is forgiving. It pulls usable JSON out of code fences, <think> blocks, trailing commas and truncated replies, and understands loose spellings such as "skip" or "defer". It retries without JSON-schema mode when a server rejects it. If the model dies halfway through a long list, the remaining tasks are finished with the keyword rules and labelled as such, instead of throwing the whole list away.
Your energy sets the size of Do now. A slider fills Do now up to that many minutes and slides the overflow to Do later, instantly and without asking the model again. Anything important that is due within two days stays put.
The boring parts are the point. The server is Python's standard library and the front end is one HTML file, one stylesheet and one script, so there is nothing to install and nothing to break. Fonts ship with the app (Atkinson Hyperlegible, under the SIL Open Font Licence) and the colour pairs were run through a contrast checker. [N] tests cover the parser, the dates, the safety net, both model clients, the pipeline, HTTP security and the command line, and [N] more drive a real browser.
What I would do next
- Teach the date finder and the safety net languages other than English. Today a model may cope with other languages, but the tripwires will not.
- Measure how often each verdict is overruled, per model, so choosing a model stops being guesswork.
- A weekly sweep: re-sort what is still sitting in Do later.
Code
github.com/SaurabhEffect/HacktoberFest-2026/tree/main/wont-do-list
Prize categories
- Best Use of Gemma: the demo above runs Gemma (gemma3:4b) locally through Ollama.
Top comments (0)