This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
slothaudit is a command-line auditor for trading-strategy repos that runs entirely offline. Point it at a folder; it runs five deterministic source checks, then a local 1.5B open-weight model reads the code each finding points at and answers one narrow question about it: is this finding actually true here?
You start it before you go to bed. In the morning you read six lines.
Why a night shift and not a chat window: the bugs that kill a backtest are boring and repetitive — a fill taken on the signal bar, a ledger that never mentions fees, one market event counted as eleven samples, a drawdown that resets its own peak. You find them when you already suspect them, which is exactly when you don't need help. So the boring pass runs while you're asleep, at sloth speed, on your own CPU.
$ slothaudit audit samples/broken_lookahead
Generated 2026-10-22 18:21, offline.
## Morning summary
FIX FIRST: samples/broken_lookahead/strategy.py:1 — no fee or slippage term in the ledger
ALSO: samples/broken_lookahead/strategy.py:9 — fill price read on the signal bar
ALSO: samples/broken_lookahead/strategy.py:1 — entries without a cooldown
## Findings
### CO-01 [high] no fee or slippage term in the ledger
samples/broken_lookahead/strategy.py:1
This file records PnL but never mentions fee, commission, slippage or spread.
Model check: **YES**
A clean repo gets the other answer, and it is deliberately not reassuring:
$ slothaudit audit samples/clean_strategy
No v0 check fired. That is not the same as clean: it means this run had
nothing to point at, not that the strategy survives an audit.
Both runs: ~13 seconds on a laptop CPU, no network.
github.com/rytjy/slothaudit — Python standard library only, no dependencies beyond the local model binary.
The split of labour is the point:
path:line from the checker. The model is never asked to name a file or a line.yes, no or unsure. That is a task a 1.5B model can do. Asking it to "write a summary" produced confident nonsense — so I stopped asking.
Prior work, credited. The five checks are distilled from my own earlier kit, backtest-audit-kit, which documents the failing cases they came from. slothaudit is a new project written this week during the challenge; the checks were rewritten as source-level heuristics and the model layer is new.
llama-cli in and out, one process per audit, nothing left running.where(x > 0, 0) turning NaN into zero.
Two design decisions came from being honest about the model size:
An audit of the broken sample takes 13 seconds and produces four findings, one of which — the missing cost term — is the kind of thing I would otherwise notice three weeks later, after wondering why a strategy that "works" loses money.
The honest comparison is not 13 seconds vs 20 minutes of expert review. It is 13 seconds vs the zero minutes I actually spend looking, because after the fifth project nobody re-reads the fill logic. That is the effort it saves: the pass that never happened.
I ran it on both sample repos this week; the clean one fired nothing, which is the result that makes the other one trustworthy.
Three concrete reasons, not slogans:
chat(prompt) — with an Ollama HTTP path first and a llama.cpp subprocess fallback. When a better 1.5B appears, I drop in a GGUF. No re-platforming, no migration, no vendor.
The 1.5B is not a placeholder for a bigger model I wish I could afford. It is a deliberate choice: the checks find the problem, the model only has to answer "is this true here?" — and a small model that answers a narrow question honestly beats a large one that writes a beautiful paragraph I cannot verify.
Built during Week 3. The repo includes the two sample strategies used above, and the audit output is reproducible byte-for-byte on any machine with the same GGUF.