This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
Siesta is a small local app that plans next week's posts while you sleep, and tells you honestly when your own history can't help.
Most "best time to post" tools hand you a confident answer whatever your data looks like. Siesta does the opposite. You give it your post history (a CSV, or public posts from DEV by username or tag). It trains a small logistic regression on your older posts, tests it on your newest 20%, and reports ranking skill (ROC AUC) with a 95% bootstrap range. If that range includes a coin flip, the verdict is "no signal", the drafts stay unranked, and it tells you to go back to sleep.
If there is a signal, you give it a brief (typed, or read from your recent git commits or a notes file) and it drafts a week of posts with titles, tags and outlines. Code, not the model, computes every feature and score. Drafts that don't score Strong get one revision, and the revision is kept only if it scores higher.
Who gets to be lazier: anyone who writes regularly and loses an hour every Sunday to "what do I write, and when?" One run answers both. And when your history shows nothing, it saves you from optimizing noise.
Demo
Siesta runs on your own computer, so there is no hosted link. I kept it local on purpose: your history and scores never leave the machine. The screenshots above come from the built-in demo data, which is made up and has a planted pattern, so the numbers in them are for trying the app only.
To try it in a couple of minutes:
git clone https://github.com/Divyansh0208/Siesta.git
cd Siesta
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python -m siesta
Then press "Just let me try it" in step 1. No key is needed; without one it uses plain templates for the drafts.
Code
Siesta 🌙
Plan next week's posts while you sleep, and find out honestly whether your own history predicts what works. If it doesn't, Siesta says so and tells you to go back to sleep.
Runs on your computer. Drafts come from Google's free Gemini API (free key, no card). No telemetry.
What it does
- History. Upload a CSV (a date, a title, a result such as reactions or likes), or pull public posts from DEV by username or tag (DEV's public API needs no key).
- Reality check. A small logistic regression learns from your older posts and is tested on your newest 20%. You see ranking skill (ROC AUC) with a 95% bootstrap range, lift for its top 20% picks, and the measured hit rate of its Strong / Toss-up / Weak groups. If the range includes a coin flip, the verdict is "no signal" and drafts stay unranked.
- Brief.…
MIT licensed. Python 3.10+, with numpy, pandas and scikit-learn. The server is the standard library only.
How I Built It
- The judge is not the LLM. A logistic regression (C=0.5) on weekday, 4-hour window, title length, question mark, number, tags, reading time and cover image. A gradient-boosting model runs on the same test for comparison and is never used to score. The method is fixed in advance: threshold, tag list and scaling come from training rows only, and seeds and settings are never tuned on results.
- The writer is Gemini's free tier. Siesta calls the Gemini REST API over plain HTTPS with no SDK, asks for JSON that follows a schema, and then validates everything. Model output is treated as untrusted: it gets one retry, and nothing numeric is ever taken from it.
- Without a key it still works. It falls back to plain templates, so the whole flow runs offline.
-
The free tier fought back. While testing I hit a 404 on
gemini-2.5-flasheven though it appeared in the model list, then 503s on an overloaded preview model, then a timeout. So Siesta now lists the models your key can use (stable ones first), retries on rate limits and overload, and moves on to the next model on a 404, 503 or timeout. Only then does it fall back to templates, and the run log says what happened. -
Everything else is small. A tiny
.envreader, a stdlib HTTP server bound to localhost, a single HTML file for the UI, and 12 tests that need no key.
Why Does Open Innovation Matter?
I want to be straight about this. The drafting step uses a hosted free API, not an open-weight model, so I'm not claiming the model itself is open. My first version used open-weight models through Ollama, and I switched to Gemini's free tier because that's what I could run.
What open innovation made possible here is the part that matters most:
- The judge is auditable. A logistic regression you can read, with the same split and settings every run, can show you why it said no. A hosted black box can't.
-
The code is open and the model is swappable. The model sits behind one small file (
siesta/draft.py). Everything the app decides, from the verdict to every score, lives in open code you can read. - Open tooling carried the project. scikit-learn, pandas and numpy do the real work, and DEV's public API needs no key.
The cost is privacy. Gemini receives your brief, your common tags and the draft being revised, while your history stays on your machine. Google may use free-tier prompts to improve its products, so keep secrets out of the brief. I put that in the README on purpose.
The Lazy Payoff
One press of "Draft my week" produces a full week of drafts, each already scored, slotted onto a day and hour, and revised once if it wasn't Strong. In my demo run, two drafts were revised and kept because they scored higher: one went from 61% to 78%, another from 57% to 73%. Those numbers come from the made-up demo data, so they show how the revise-and-keep rule works, not a promise about your posts.
I haven't claimed hours saved, because I haven't measured them on real posting history yet. The honest payoff is smaller and, I think, more useful: it either hands you a week of drafts, or it tells you in one run that your history can't predict anything and you can stop fiddling.



Top comments (0)