# ofrenda — lighting a candle for the files your repository deleted

> Source: <https://dev.to/justchill/ofrenda-lighting-a-candle-for-the-files-your-repository-deleted-4fn>
> Published: 2026-10-31 06:40:30+00:00

*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine](https://dev.to/challenges/hacktoberfest-week4-2026-10-26)*

**Every git repository is a graveyard, and nobody holds the ceremony.**

Somewhere in your history there's a `pricing.html` that shipped before the

product existed, an `app_v2.py` from the rewrite that never finished, a

stylesheet in hotpink you were proud of for six hours. `git log` will tell

you *when* they died. It will never tell you what they meant — so they rot,

unmourned, while you scroll past their filenames looking for something else.

**ofrenda** is the ceremony. It's a Día de los Muertos altar for your code:

``` bash
$ ofrenda examples/graveyard-repo

ofrenda :: 4 departed :: model gemma3:4b

  [1/4] app_v2.py
          “Served 'eventually'. Rest now.”
  [2/4] index.html
          “A valiant start, now dust.”
  [3/4] pricing.html
          “A valiant, if misguided, attempt.”

  4 remembered, 0 unspoken

  ofrenda lit → …/ofrenda.html
```

The tool walks your history for every deleted file and digs up its whole

life: the commit that created it, the people who touched it, how many

commits it survived — and, on the eve of its death, the literal content it

was still carrying. Then it hands that record to a model running **on your own machine** and asks it to say a few words. What comes back is one

I interpreted "Ghost in the Machine" this way: the ghosts aren't monsters,

they're *the dead we didn't memorialize*, and the machine finally gets to

speak for them. Halloween gives you the graveyard; Día de los Muertos tells

you what to do there — remember deliberately, warmly, and with candles.

Who this is for: anyone who has ever rewritten a project "from scratch" and

later wondered what the old version actually did; maintainers doing cleanups

who want a moment of gratitude before the `rm`; teams onboarding someone who

needs to understand not just what exists, but what was tried and abandoned.

No deployment needed — it's your own machine, and the page it prints is a

single file you can open with the Wi-Fi off.

```
git clone https://github.com/itzneel05/ofrenda && cd ofrenda
ollama pull gemma3:4b
pip install -e .

python examples/make_demo_repo.py   # grows a small graveyard to mourn
ofrenda examples/graveyard-repo      # writes ofrenda.html
```

Real captured output — four dead files, four eulogies, straight from

`gemma3:4b`:

```
ofrenda :: 4 departed :: model gemma3:4b

  [1/4] app_v2.py
          “Served 'eventually'. Rest now.”
  [2/4] index.html
          “A valiant start, now dust.”
  [3/4] style.css
          “A vibrant blush, now gone.”
  [4/4] pricing.html
          “A valiant, if misguided, attempt.”

  4 remembered, 0 unspoken

  ofrenda lit → C:\...\ofrenda.html
```

And what the model wrote for `pricing.html`, verbatim from `--json`:

```
{
  "path": "pricing.html",
  "epitaph": "A valiant, if misguided, attempt.",
  "story": "Launched with a bold promise of zero cost, pricing.html bravely represented the nascent product — a testament to early enthusiasm and, frankly, a bit of optimism. Its short existence ended abruptly when the Demo Author deemed its message 'sad'.",
  "cause_of_death": "deleted",
  "beloved": ["Zero cost", "Early optimism", "A brief, memorable moment"]
}
```

Every claim in that story is grounded in evidence the tool actually fed it:

the file's content (`<h1>Only $0 — because nothing works yet</h1>`), the

commit that killed it (`fix: pricing page was making everyone sad`), and

its two-commit lifespan.

Other flags: `--limit 10` (ten newest deaths), `--model gemma3:1b`

(smaller machines), `--json` (for scripting), `--out altar.html`.

[https://github.com/itzneel05/ofrenda](https://github.com/itzneel05/ofrenda)

`ofrenda/gitdead.py` — the archaeology: `git log --diff-filter=D` for
deaths, `--follow` for birth/lifespan/contributors, `git show <death>^:<path>`
for the content at death. Parses git's raw record separators byte-carefully
(a fun bug: Python's `splitlines()` treats `\x1e` as a line break, which
silently swallowed every finding until a test caught it).`ofrenda/eulogy.py` — prompt built from the evidence, plus a tolerant JSON
parser for whatever the model decides to wrap it in (fences, chatty
prefixes, trailing "Hope that helps!").`ofrenda/client.py` — stdlib Ollama client. No base-URL flag, no API key:
`127.0.0.1:11434` and nowhere else.`ofrenda/render.py` — the altar itself: one HTML file, zero scripts, zero
CDNs, everything escaped.`tests/` — 24 tests, 

```
flowchart TD
    A["git log --diff-filter=D<br/>which files died, and who killed them"] --> C["life record per file"]
    B["git log --follow + git show death^:path<br/>birth, lifespan, contributors, final content"] --> C
    C --> D["prompt built from the evidence"]
    D --> E["gemma3:4b on 127.0.0.1:11434<br/>(local, via Ollama)"]
    E --> F["epitaph · story · cause of death · beloved[]"]
    F --> G["HTML-escaped into one self-contained<br/>candle-lit ofrenda page"]
```

Zero runtime dependencies. Python 3.9+, `git`, Ollama, done.

Built with AI assistance in OpenCode, with Google's open-weight Gemma 3 running locally through Ollama.

Because the code that gets deleted is often the code you'd least want to

upload. Personal projects with your real name in the history. A client's

proprietary logic you still have an NDA about. The half-finished side

business. A repository that contains a layoff's worth of commit messages.

Asking a cloud API to read every deleted file in your history — and write

about your team while it's at it — is a question you'd never get a yes to,

which is exactly why the tool would be useless if it asked.

With an open-weight model on localhost:

`--model gemma3:1b` for speed, fine-tune
Gemma on I didn't expect this part to land. The demo repo is synthetic — six commits

I wrote ten minutes earlier — and the model still produced, for a

two-line file named `app_v2.py` that returned the string `'eventually'`:

*"Served 'eventually'. Rest now."*

That's a two-line function getting a headstone. I ran it again and got a

different epitaph, same feeling. The point of Día de los Muertos was never

accuracy about the dead — it was the remembering. A tool that makes you stop

and read what your `cleanup` commit actually destroyed, for eight seconds

per file, on your own machine, is a small machine for exactly that.

`gemma3:4b` (and `gemma3:1b`) via Ollama is the
sole author: every epitaph, story, cause of death and beloved-trait list
comes from the model. There is deliberately no template fallback — if the
model is missing, the tool stops, because a mad-libs condolence would
miss the entire point.
