ofrenda
An altar for everything that died on your machine. ofrenda finds the real deaths on your computer this week (OOM kills, crashed services, dead containers, app crash reports, or fatal lines in any log), asks a local open
An altar for everything that died on your machine.
ofrenda finds the real deaths on your computer this week (OOM kills, crashed services, dead containers, app crash reports, or fatal lines in any log), asks a local open-weight model to write each one a short calavera literaria (the wry Mexican epitaph tradition) and one practical offering (the fix that would keep the next one alive), then builds a terminal altar and a single-file HTML ofrenda. Taller candle, longer life.
Built for the DEV Hacktoberfest Open-Source AI Challenge, Week 4: Ghost in the Machine.
Quick start
Needs Python 3.9+ and Ollama. No pip packages.
bash
ollama pull gemma3:4b # any Ollama model works; Gemma is the default
git clone https://github.com/Ayush7-BIT/ofrenda && cd ofrenda
python3 ofrenda.py --demo # made-up deaths, so you can see it work anywhere
python3 ofrenda.py # the real ones, last 7 days
open ofrenda.html # xdg-open on Linux
No model handy? python3 ofrenda.py --demo --no-llm uses plain template epitaphs.
Where the dead come from
Source Reads Works on
Docker exited containers with a non-zero code: exit code, OOMKilled, start and finish times, last log lines anywhere Docker runs
systemd systemctl --failed, plus the unit's last journal lines Linux
Kernel OOM journalctl -k (or dmesg) lines for "Out of memory: Killed process" Linux (may need the adm group or root)
Crash reports ~/Library/Logs/DiagnosticReports/*.ips and *.crash: exception type, signal, launch and crash time macOS
Any log --logfile PATH (repeatable): lines that look like a death (OOM, segfault, panic, fatal, non-zero exit) anywhere
Copy a log off a server and scan it offline: ssh prod 'journalctl -k --since "7 days ago"' > kernel.log, then python3 ofrenda.py --logfile kernel.log.
Privacy
Logs are the most sensitive text a machine produces. So:
Inference runs through Ollama on localhost. Nothing is sent anywhere unless you set OLLAMA_HOST to another host (the HTML footer says so when you do).
Before the model sees anything, secrets are scrubbed: AWS keys, JWTs, token=/password=-style pairs, emails, IPv4 addresses, and your home directory. Turn it off with --no-redact.
Control characters are stripped from every log line, so a hostile log cannot write escape codes to your terminal. All text in the HTML is escaped.
The model gets only the facts for one process at a time: name, how long it lived, how it died, and up to three last lines.
Options
Flag Meaning
--days N how far back to look (default 7)
--max N most souls to honor (default 8)
--logfile PATH also scan this log (repeatable)
--demo use made-up deaths
--html FILE where to write the altar (default ofrenda.html)
--model NAME any Ollama model; or set OFRENDA_MODEL
--no-llm template epitaphs, no model
--no-redact do not scrub secrets, IPs and emails
How it works
Each collector turns a death into a Dead record: name, kind, cause, how long it lived, when it died, last words.
The record is scrubbed and sent to the model with a system prompt that allows only the facts given, and a JSON schema (epitaph, offering) passed through Ollama's structured-output format option. That is what keeps a 4B model from rambling.
The HTML renderer draws one candle per process. Candle height is 26 + 38 * log10(1 + minutes_lived) pixels, capped; a dashed stub means the lifespan was never recorded.
Limits
Small models sometimes write lines that do not rhyme, or add a fifth line. The facts are still right, because the prompt forbids inventing any.
The model only sees what is in the logs. If a cause of death is unclear, the offering says what to check first rather than guessing.
The first call fails fast with a clear message if Ollama is not running or the model is not pulled.
Tested on
Fill in before publishing: OS, Python version, Ollama version, model, which sources actually found deaths.
Timeline
First commit: 31 October 2026, inside the challenge window. Any commit after the deadline will be listed here.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.