This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
There are two pieces of writing I put off as a CS student. One is the commit message at 11:40 pm, when the bug is finally fixed and my brain has nothing left. That's how my history ends up full of fix, fix2, ok now it works and the classic asdf. The other is the weekly "so what did you do this week?" update, which always means scrolling back through those same useless commits to work out what I actually did.
SlothCommit hands both jobs to a small open-weight model running on my own machine:
-
sloth commitreads my staged diff and writes a Conventional Commit (fix(cli): ..., with a short body), then asks Yes / Edit / No. -
sloth weekturns the last 7 days of commits into a changelog grouped by type, with a 2–4 sentence summary I can paste into a standup or group chat.--lang zhwrites it in Chinese. -
sloth hook installis for when even typingslothis too much. It adds aprepare-commit-msghook, so a plaingit commitarrives with the message already filled in. If the model is down, the hook gets out of the way and never blocks the commit.
The model is Gemma 3 1B, running through llama.cpp. No API key, no account, no per-token bill, and no diff ever leaves localhost.
It's for anyone who writes code and hates writing about code, and for every teammate who has to read git log afterwards.
Demo
A real terminal session, recorded with asciinema. The GIF renderer caps idle pauses at 2 seconds, so the timings Gemma prints in the terminal are the real ones. Every model output is unedited Gemma 3 1B, running on a 2-vCPU ARM cloud box with no GPU:
To be upfront: the repo in the demo is a small GPA calculator I wrote just for the recording. Its first six commits were also written by sloth commit, then backdated so sloth week had a week to summarise.
Code
🦥 SlothCommit
Let a local Gemma model do the git chores you keep putting off.
Writes your commit messages, your weekly "what did I even do" report, and
(if you're truly committed to laziness) fills in git commit for you
Offline. Free. Your code never leaves your machine.
$ git add -A && sloth commit
🦥 Gemma via llama-server: 4.8s. Nothing left this machine.
fix(cli): add GPA calculation fix
- Fixed a potential error in the GPA calculation by adding a check for
unknown grades and raising an UnknownGradeError
...
(That's a real, unedited output from Gemma 3 1B. It's a first draft, not
an oracle: sloth commit asks Yes / Edit / No before committing. Every commit
in this repo's history was written by SlothCommit and left unedited, so you
can judge the quality yourself.)
What it does
| Command | Chore it removes |
|---|---|
sloth commit |
reads git diff --cached
|
About 940 lines of Python (plenty of it docstrings) and no runtime dependencies (the in-process backend is an optional extra). There are 30 tests, MIT license, and a CI workflow. The tests swap Gemma for a fake backend, so they run in 0.2 seconds with no model. Credits for everything I built on are in CREDITS.md.
There's one more thing I'm a bit proud of: every commit that built the tool was written by SlothCommit and pushed unedited. (The one exception is a later hand-written touch-up to the demo GIF, and its message says so.) You can judge the quality yourself, and I'll say below where it falls short.
How I Built It
The stack. I used Gemma 3 1B instruction-tuned, as the Q4_0 GGUF from unsloth/gemma-3-1b-it-GGUF, an ungated conversion, so the first run is a plain download with no Hugging Face login. It runs on llama.cpp's llama-server. SlothCommit has three backends and picks whichever is available: llama-server, then Ollama (gemma3:1b), then in-process llama-cpp-python. (Honesty note: the Ollama backend is unit-tested against Ollama's documented API, but I couldn't get the Ollama binary to download in my sandbox, so all the numbers below are from llama.cpp.)
The real work was keeping a 1B model honest. My first version just sent the diff with a list of rules. On my 7 test diffs, Gemma wrote "handle empty input in parser" for four of them, which was the example sentence from my prompt. So the design ended up as "Gemma does the part that needs language, and Python does everything else":
-
Schema-constrained output. Gemma has to answer with JSON matching
{type, scope, subject, body}, andllama-servercompiles that schema into a grammar. The output always parses, andtypeis always one of the ten valid commit types. It can't answer with a poem. -
Facts in code, not in the prompt. If only Markdown files changed, I narrow the schema's
typeenum to justdocsbefore Gemma sees it. The same goes for tests, CI, and brand-new code files (feat). Scope cleanup (gpa.py→gpa), the 72-character header, line-wrapping and de-duplicating the body are all plain Python. -
Few-shot instead of rules. Three tiny examples (a README edit, an HTTP timeout fix, a pomodoro timer) taught the format far better than a paragraph of instructions. They never change, so
llama-servercaches that prefix. A warm request only has to read my diff. - Condense big diffs instead of truncating them. Small diffs go in as they are. Big ones (new modules, mostly) are cut down to each file's definitions, comments and docstrings. In that case Gemma isn't allowed to write bullet points, because with only an outline its "details" were mostly made up.
-
A homework-copying detector. This was my favourite bug. When I pointed SlothCommit at its own source code, the first batch of new files came back as
docs(readme): add install instructions. A later one wasfix(http): add request timeout and raise on http errors, word for word my few-shot example. Gemma had given up on the diff and copied its homework. Now, if the subject shares most of its words with one of the examples, SlothCommit says so and falls back to a boring but true message built from the file list. - The weekly report never invents the changelog. Grouping commits into Features, Bug fixes, Docs and so on is deterministic code. Gemma only writes the summary on top. For Chinese I use a prompt written in Chinese, because asking for Chinese in an English prompt got English back.
Two sandbox stories that made it into the code:
- My requests to
localhostkept returning 404. The machine had an HTTP proxy configured, and Python'surllibwas politely sending my diff to it. SlothCommit now builds a proxy-free opener for local backends. That fixed the bug, and it also means a system proxy can never quietly carry your code anywhere. - Speed:
llama-cpp-python's prebuilt wheel read prompts at about 25 tokens/s. The official llama.cpp ARM build with the Q4_0 quant read them at 182 tokens/s, because Q4_0 gets repacked for the CPU's int8 matrix instructions. A commit message is mostly reading a diff and barely writing, so that one choice made the tool usable. (Along the way I also filled the sandbox's RAM-backed disk with a 4B model and an Ollama tarball, and spent a while confused about why every download came back 0 bytes. Sloth tip: rundf -hfirst.)
Why Does Open Innovation Matter?
For this project, open weights aren't a philosophy slide. Each item below is something that would have broken with a closed API:
-
The code never leaves the machine. A commit tool reads everything you write: coursework you're not supposed to share, internship code under an NDA, half-finished research. With a local Gemma, the whole data flow is "your disk → your RAM → your
.git". I didn't have to write a privacy policy because there's nothing to have a policy about. - It costs nothing and needs no account. A tool you run on every commit can't come with a per-token bill or a credit card form, especially for students. Also, several big hosted model APIs don't officially serve mainland China. An ungated GGUF and an MIT-licensed runtime work the same everywhere, offline included.
- I could look inside and fix things. Every fix above came from having the whole stack open. I benchmarked quantizations myself and picked Q4_0 for a reason I can point to. I cached the few-shot prefix in the server and narrowed the grammar per request. When the model misbehaved I could see exactly what it was given and why. With a closed endpoint I'd just be tweaking a prompt and hoping.
-
It can be swapped. Want a smarter sloth? Set
SLOTH_OLLAMA_MODEL=gemma3:4bor pointSLOTH_MODELat any GGUF. Nothing in SlothCommit is tied to a vendor.
The honest trade-off: a 1B model is a first-draft writer, not an oracle. That's why sloth commit asks before committing and the changelog is built in code.
The Lazy Payoff
Only numbers I actually measured. All of them come from a 2-vCPU ARM cloud box with no GPU, running Gemma 3 1B Q4_0 on llama-server. A normal laptop should do at least as well.
| What | Measured |
|---|---|
sloth commit on the demo repo, 8 commits |
2.2 – 4.8 s each, mean 3.4 s |
| SlothCommit writing its own 10 build commits (bigger diffs) | 3.0 – 8.5 s each, mean 5.4 s |
sloth week (6–7 commits, English or Chinese) |
3.0 – 4.7 s |
| Small diff with the server warm vs. its very first request | 1.1 s vs. 8.2 s |
Same diff in-process through llama-cpp-python
|
67.9 s (use the server!) |
Memory used by llama-server
|
~1.6 GB |
| Cost | $0, no network after the ~720 MB model download |
I didn't measure how long I used to spend on commit messages, so I won't invent a "saves 2 hours a week" number. What I can say for sure is that this week, 11 commits went into SlothCommit's own history and I typed exactly zero characters of those messages.
How good are they? About what you'd expect from a 1B model in a hurry. Most are fine. A few are sloth-quality: a .gitignore commit typed as feat, a body claiming it "improves performance" that nobody measured, one test(tests): add test_git_and_cli.py that is technically true and spiritually lazy, and my favourite: a README edit summarised as docs(readme): add GPA calculation fix, because the README quotes that line from the demo and Gemma simply quoted it back. The Chinese weekly summary sometimes adds achievements that never happened, so I read it before sending. My plan: keep the guard rails tight, and let anyone with more RAM switch to Gemma 3 4B.
Prize Categories
Best Use of Gemma. Gemma 3 1B is the only model in SlothCommit and does every piece of writing in it: commit subjects and bodies, plus English and Chinese weekly summaries. The project is built around what a 1B Gemma can and can't do on a CPU: schema-constrained decoding, few-shot prompts with a cached prefix, deterministic type narrowing, condensed diffs, and a detector for when it copies its examples. It runs fully local through llama.cpp or Ollama, offline and free.


Top comments (0)