DEV Community

Anurag Yadav
Anurag Yadav

Posted on

Revenant: a séance for dead git repositories, where the ghost can't lie

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

Every abandoned repository is a small grave with a very good diary. The commits are all still there: who showed up, what they fixed, and the last thing anyone said before the silence. I wanted to let people visit.

Revenant is a séance for dead git repositories. Paste the address of a public repo and it gives you:

  • A coroner's report: birth date, last breath, how many days it has been silent, its longest sleep, and a cause of death, from abandoned by its only keeper to bus factor of one.
  • An ofrenda: one flickering candle for every person who kept the project alive, sized by how much they gave, followed by the project's last words, which are its final commit messages.
  • A ghost you can question: ask why did you go quiet? or what were you most proud of? and the repository answers in the first person.
  • A downloadable memorial: save the whole ofrenda as a single HTML page to keep.

I took the theme from both sides. "Ghost in the Machine" is literal here: a ghost speaking from inside a codebase. The ofrenda is my nod to Día de los Muertos, where you remember people by lighting a candle and telling their stories. A repo's contributor list is a very small version of that.

The rule that makes it work is the rule of the dead: the ghost may only say what the record says. Every claim must cite a commit hash. Revenant then checks each hash against the commits it actually retrieved, and any citation that doesn't exist is struck out and marked unverified. A ghost story where the ghost cannot make things up.

Demo

Live: https://revenant-jcai.onrender.com/

Paste any public GitHub, GitLab or Codeberg repo, for example https://github.com/octocat/Hello-World, and press Dig it up.

One honest note about how the demo is wired. The web app is hosted on Render, but the model, Gemma, runs on my own laptop and is reached through a tunnel. If my laptop is asleep, the app says "No medium connected" and the ghost falls back to repeating the repository's own commit messages. I built that fallback on purpose, and it is still fully usable. The live link may therefore show either the model's answers or the fallback.

Code

https://github.com/ypunit757-prog/revenant-app

How I Built It

Open-weight model, local inference. The ghost is Gemma 3 (1B) served locally by Ollama. The server talks to any OpenAI-compatible endpoint through one environment variable (LLM_BASE_URL) and one model name (LLM_MODEL), so swapping Gemma for another open model means changing a setting, not code.

Zero-dependency Node backend. It is a plain Node http server with no framework and nothing to npm install. For each request it:

  1. Clones the repo history as a bare, blobless clone (just the commit metadata, no file contents) into a temp folder, reads the log, and deletes it.
  2. Computes the autopsy: dates, silence, longest gap, contributor counts, and a cause of death.
  3. Retrieves the commits most relevant to your question with BM25 ranking written from scratch. There is no vector database and no embedding download, so it is light enough to run on a free host.
  4. Sends only those commits to the model as evidence, with strict instructions to cite hashes and to answer "The record is silent." when the evidence doesn't say.
  5. Runs the citation check: any [hash] the model produced that isn't in the evidence is removed and flagged, and the reply shows a "citation integrity" percentage.

Vanilla JS front end. There is no framework. The page is built from a few small functions with a typewriter effect and flickering CSS candles. Reduced-motion is respected, there are visible keyboard focus states, and it works on mobile. Commit messages come from strangers, so everything is rendered with textContent and never as HTML, which means a hostile commit message can't inject anything.

Safety rails. Only HTTPS repo URLs from GitHub, GitLab and Codeberg are accepted, git is run without a shell, clones time out after 90 seconds, history is capped at 20,000 commits, and each visitor is limited to 20 requests a minute.

Deployment. The app runs as a Docker web service on Render, with git installed in the image. Render hosts the front end and API, and the model stays on my machine.

Also included. The repo ships the original terminal version in cli/revenant.py. It uses only the Python standard library and runs fully offline against local repositories, including private ones.

AI assistance. I built this with an AI coding assistant (Claude), which the challenge allows, and I tested and ran the result myself with Gemma through Ollama.

What it can't do. A 1B model is small, and it doesn't always follow the citation format. That is exactly why the checker exists. The checker verifies that a cited commit really exists in the evidence. It does not prove the model's sentence is a faithful summary of that commit, so the clickable hash chips, which link to the real commit, are how a reader verifies a claim.

Why Does Open Innovation Matter?

A repository's history is often the only surviving memory of what its people were thinking. A memorial built on a closed API depends on someone else's servers, pricing and terms staying friendly. That is a fragile place to keep a memory.

Open pieces made three things possible here that I wouldn't have had otherwise:

  • I control the rules of the dead. Because I run the model and the prompt myself, I could enforce "cite or stay silent" with my own verification step after generation. The trust in this project comes from the checking layer I could build around the model, not from the model's goodwill.
  • I can swap the model with a setting. Gemma today and another open-weight model tomorrow, with the same code. Nothing about the project is locked to a vendor that might change or disappear.
  • It still works with the lights out. The terminal version needs no network at all, so private repositories never leave the machine, and even the web app degrades gracefully to quoting the record when no model is reachable. It also costs nothing per question, because inference runs on hardware I already own.

For a project about remembering things before they vanish, it felt right that the thing doing the remembering shouldn't be able to vanish either.

The Spirit of It

The part I care about most is a small moment of refusal. Ask the ghost something the commits can't answer, such as "were you happy?", and it will say: "The record is silent." It isn't allowed to comfort you with something it made up. And when a model does slip and cites a commit that was never made, the reader sees that citation crossed out and labelled unverified.

Remembering the dead honestly means not putting words in their mouths. A repository can only tell you what it did, and that turns out to be enough to make you feel a little of what it was like to be there.

Prize Categories

  • Best Use of Gemma: the ghost is Gemma 3 (1B), running locally through Ollama, with the model swappable via an environment variable.
  • Best Use of Render: the web app, which is the agent's front end and API, is deployed as a Docker web service on Render.

Top comments (0)