DEV Community

Adeogun Joseph Daniel
Adeogun Joseph Daniel

Posted on

Ofrenda: tributes for the developers a project forgot, written offline by Gemma 3 1B

Hacktoberfest Open-Source AI Challenge: Ghost in the Machine Submission 👻🌼

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine

What I Built

Ofrenda reads the git history of a project, finds the contributors who stopped committing, and writes a short remembrance for each one. You give it a GitHub link or a folder. It prints a report in the terminal and saves an HTML page with a tombstone for every developer who left, a timeline of who stayed and who went quiet, and a list of files nobody has touched since their last author walked away.

The name comes from the ofrenda, the altar families build for Día de los Muertos to keep the dead in the conversation. Every old repository already holds who worked on it and what they said last, in the form of commit messages sitting in git log where nobody reads them. I took "ghost in the machine" literally. The ghosts are people, and the machine remembers them whether or not anyone asks.

It is for anyone who has inherited a codebase and wondered who wrote it.

Demo

The video runs it on one of my own projects, on two older open-source projects (request and bower), and once with the internet off. To try it yourself you need Python, Git and Ollama, then:

ollama pull gemma3:1b
python ofrenda.py https://github.com/request/request
Enter fullscreen mode Exit fullscreen mode

Code

Ofrenda

An offering for forgotten developers.

Ofrenda reads the history of any git project, finds the contributors who stopped showing up, and writes a short remembrance for each one with a small local model (Gemma 3 1B through Ollama). Everything runs on your own machine. Nothing is uploaded.

The names, dates and counts are printed by plain code. The model only writes two sentences per person, and a checker throws away any sentence that invents a number, date or file name.

Quick start (3 steps)

  1. Install Python, Git and Ollama.
  2. Download the small model once: ollama pull gemma3:1b
  3. Run it on a GitHub link or a folder:
python ofrenda.py https://github.com/octocat/Hello-World

That is all. There is nothing to pip install.

Not sure what to give it? Run python ofrenda.py with nothing after it and it will ask you for a folder or a link.

On Windows without typing

Double-click…




Python standard library only, so there is nothing to pip install. The README has a three-step quick start. On Windows, haunt.bat asks for a link or folder and opens the result in the browser.

How I Built It

The model is Gemma 3 1B (gemma3:1b, 806 MB) running through Ollama on a laptop with 3,917 MB of RAM. Ofrenda calls Ollama's local HTTP API with a 2,048 token context.

A 1B model is unreliable with facts. My first prompt handed it a pile of details about each developer, and it wrote that a .gitignore file had been "finalized" five months earlier. That never happened. So I split the job. Plain code reads git log, decides who counts as gone, and prints every name, date and count itself. Gemma gets three facts per person (first name, last commit message, most-edited file) and writes two sentences.

Then a checker reads what Gemma wrote. A sentence is thrown away if it mentions a number, date or file name that was not in those facts, or if it quotes something that does not match the real commit message. A quote that is close gets replaced with the exact text. If three tries all fail, Ofrenda falls back to a plain sentence built from the data, so the page never shows an invented fact.

Testing on real repositories added more rules. Bot accounts are skipped, and contributors are ranked by commit count so the first ghost is the person who gave the most. An --alias option merges two git names for one person, because my own project listed me twice. GitHub links are cloned as history only, with no file contents, and deleted after the run. make_gallery.py runs the tool over a list of links and builds an index page.

The 1B model still repeats itself. "A silent monument" and "the flame flickers" appear more than I would like, and it sometimes says a project feels incomplete when it cannot know that. The checker can verify facts, not taste.

I built this with Claude as a coding assistant, and I ran every change on my own laptop. Some bugs only showed up there. One was my cleanup code stripping the # out of (#3267) inside a quoted commit message, which I saw on the gallery page.

Why Does Open Innovation Matter?

I ran Ofrenda on a project already on my disk with no internet connection, and it worked the same. A repository's history holds real people's names and habits. With an open model that history stays on my machine. The only network use is fetching a GitHub link once, and you can skip even that by pointing at a folder.

Having the weights also gave me control a hosted API would not. I could pin one exact model, cap its memory use so it fits on a 4 GB laptop, and retry a bad answer as often as I wanted with no cost per call.

A tool about things being forgotten should also not stop working because a service shut down. As long as the files are on the disk, it runs.

The Spirit of It

I ran it on one of my own projects, an app I last committed to in May. Ofrenda counted me as a ghost: two git identities merged into one, 83 commits, last words "redeploy: trigger vercel build". Gemma wrote to me in the second person:

Adeogun, your last message was a declaration of completion, and WalletTab.tsx still holds a silent echo of your work. Tonight, a single candle illuminates the remnants of your project.

[ADD ONE OR TWO SENTENCES: what it felt like to see your own last commit message read back to you.]

In the gallery, the first ghost for request is Mikeal Rogers, who wrote 623 commits over ten years. The last thing he wrote was a note that the project was deprecated: doc: note full deprecation (#3267). The tool had no idea that was poetic. It printed the commit message in quotes and moved on.

Prize Categories

Best Use of Gemma

Top comments (0)