This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
Every developer owns a few ghosts. A repo you loved at 2 AM. A library your project still depends on, whose last commit says "WIP" from three years ago. A tool you always meant to come back to.
When open source goes quiet, the usual verdict is a red badge or a stale-bot comment. That is a cold way to treat work someone once cared about, and it is often wrong: a finished, stable library looks "quiet" and is perfectly healthy.
The Software Cemetery gives those repositories a respectful send-off instead. Paste in any public GitHub repository and it:
- collects the public traces the repo left behind: commits, issues and pull requests, releases and contributors;
- gives it a vitality score from 0 to 100 using rules you can read in a single file, with no black box;
- builds an evidence ledger, where every claim (
E1,E2, ...) links to the exact GitHub page that supports it; - asks a local Gemma model to write a short, nostalgic, gently sarcastic life story with a citation after every factual sentence;
- and then checks those citations in code, so an invented
[E99]gets flagged instead of trusted.
I read the "Ghost in the Machine" theme through its DĂa de los Muertos side: remembering with affection, never mocking. The jokes are about TODO comments and "I'll refactor it this weekend" energy, never about the maintainers. Every story ends with a practical way to revive the project (read the latest issues, check the contributing guide, ask whether help is welcome), and it says the one thing I most want people to take away:
A quiet repo is not a dead repo.
Who it is for: developers deciding whether a dependency is safe to adopt, contributors looking for a project that needs a hand, and anyone who enjoys a good open-source ghost story.
This also fits the theme's own suggestion of bringing a forgotten corner of open source back to life: the app does not just label a project, it points you to the next respectful step.
Demo
- Live demo: software-cemetery.onrender.com
- Video walkthrough: below
How to try it in a minute: open the live demo, type a repository such as pallets/flask (or paste any public GitHub URL), and press the arrow. You get the vitality score, the story, the reasons behind the score, and the evidence ledger with a clickable source for every claim. You can also compare 2 to 5 repositories side by side, export any case as a Markdown report, and revisit your last 12 cases (stored only in your own browser).
The app also includes an illustrative sample case, clearly labelled as synthetic, so you can explore the interface without any GitHub data.
Honest note about the hosted demo: the live site runs on Render, which cannot host a local Ollama model. So the hosted demo writes its stories with the built-in evidence-linked template, and tells you so on screen. The Gemma-written eulogies come from running the app on your own machine with Ollama, which is exactly the "local and private" setup this challenge is about. If the demo is asleep when you open it, give it a moment to wake up.
Code
KomalDeep355
/
software-cemetery
An evidence-first open-source repository lifecycle investigator that analyzes GitHub activity, uncovers signs of abandonment, and generates forensic case files documenting the story behind every repository.
🪦 The Software Cemetery
FOSS has feelings. The receipts have links. Type in any public GitHub repository and get a kind, funny life story for it, written by a local open-weight model (Gemma via Ollama) and backed by a vitality score and an evidence ledger you can click and verify.
Submission for the Hacktoberfest Open-Source AI Challenge, Week 4: Ghost in the Machine 👻🌼
Table of contents
- What it is
- How it fits the "Ghost in the Machine" theme
- Demo
- Quick start
- How it works
- The open-source AI at the core
- How the vitality score is calculated
- Usage: web app, CLI and API
- Configuration
- Project structure
- Tests
- Deploying
- Honest limitations
- Challenge window and attribution
- License
1. What it is
Some open-source projects go quiet. Maintainers move on, jobs change, life happens. The Software Cemetery gives those repositories a respectful send-off, without pretending that quiet means dead.
For any public repository…
MIT licensed. The README covers setup on Windows, macOS and Linux, the full scoring table, the HTTP API, the CLI, and the limitations.
How I Built It
The pipeline
owner/repo ─► GitHub REST API (5 calls: repo, commits, issues/PRs, releases, contributors)
─► features: days since last commit, release age, contributor concentration…
─► vitality: transparent rules, 0-100, with human-readable reasons
─► evidence: E1…En, each linked to a real GitHub page
─► story: local Gemma 3 via Ollama (or an evidence-linked template if Ollama is off)
─► citation check in code: every [E#] must exist in the ledger
─► case file: score, story, evidence, limitations, Markdown export
It is Python and FastAPI on the back end, with a CRT/terminal-style front end and a pixel-art cemetery, because a tool about nostalgia should look like an old terminal at night. GitHub responses are cached on disk, with retries and rate-limit waiting, so repeat lookups are fast and polite to the API.
The open AI at the core
The writer is Gemma 3 (4B), an open-weight model, run locally through Ollama. The prompt hands it only the facts the app fetched (repository data, computed features, the assessment and the evidence ledger) and tells it to:
- use nothing but those facts,
- put an
[E#]citation right after each factual claim, - never invent maintainers' intentions, causes, users or dates,
- say plainly that inactivity is not proof of abandonment,
- end with a practical revival suggestion.
The model is swappable: change OLLAMA_MODEL in .env and the whole app uses a different one. In the interface, a single toggle ("Ask local Gemma/Ollama to write the eulogy") switches between the model and the template.
The score has no secrets
The score starts at 100 and subtracts for each warning sign. The rules live in one function, so anyone can audit the weights:
| Signal | Condition | Points removed |
|---|---|---|
| Last commit or push | no timestamp | -25 |
| over 730 days | -48 | |
| 366 to 730 days | -35 | |
| 181 to 365 days | -20 | |
| 91 to 180 days | -10 | |
| Last release | none found | -8 |
| over 730 days | -12 | |
| 366 to 730 days | -6 | |
| Contributors | one or fewer observed | -12 |
| Concentration | one author wrote 85%+ of observed commits | -8 |
| Archived | flag set | score capped at 35 |
So a repo whose last commit was 400 days ago, with no release and a single contributor, scores 100 - 35 - 8 - 12 = 45 and gets the label Quiet. Archived repositories are capped at 35 but are deliberately not treated as proof of abandonment, because plenty of projects are archived precisely because they are finished.
The labels are Recently active (180 days or fewer), Cooling down, Quiet, Very quiet, Unknown activity and Archived, and the interface always shows the reasons next to the number.
A citation is not proof, so I check it in code
Telling a small model "cite your sources" in the prompt is a request, not a guarantee. So the guardrail is code: verify() extracts every [E#] from the story and compares it with the ledger, and any id that does not exist is reported as an unknown citation. If the model call fails, times out or returns too little text, the app falls back to a deterministic template built from the same ledger and shows the reason on screen. Every story is therefore either model text that was checked, or template text that is true by construction.
I am upfront about what this cannot do: the check proves that an id exists, not that the sentence is actually supported by that source. The interface says so on every report, and the README repeats it.
The honest failure: the function that was never written
Near the end I ran the app on a real repository and nothing came back. Every investigation failed. The pipeline called GitHubClient.snapshot(), and that method did not exist.
The part that stung: my tests were green the whole time. They used a fake client, and the fake client had a snapshot() method. The tests were testing my fake, not my code.
The fix was to write the real method; add a parser that accepts owner/repo, full URLs, .git URLs and SSH URLs; make the secondary endpoints fail softly (so a refused contributors list on a huge repo does not kill the whole report); and add tests that exercise the real client's snapshot() against GitHub-shaped data. The suite is now 20 tests and runs fully offline.
It is a fitting bug for a project about forgotten code: the function everything depended on had quietly never been written.
Limits I am not hiding
- The score weights are hand-set and not yet validated against a human-labelled benchmark. The repo includes an evaluation script for when I label one, and I report no accuracy numbers because I have none.
- GitHub data is a recent sample (latest commits, issues and releases), not a complete history.
- Small local models can still slip, which is exactly why every claim links to its source.
- Without a GitHub token, GitHub allows only 60 requests per hour, and one investigation uses about 5, so heavy use needs a token.
Why Does Open Innovation Matter?
It works with the lights off. Once a repository's data is cached, the eulogy is written on my own laptop with no internet and no AI vendor. For a project themed around ghosts and blackouts, that felt right.
Nothing leaves the machine. The facts being summarised go to a model running on my own hardware, not to a hosted AI service.
No lock-in, no bill. A project about things that get abandoned should not depend on a paid API that could change its terms or vanish. Gemma on Ollama costs nothing per story, and swapping the model is a one-line change.
I can see and steer every step. Because the model is local, I can rework the prompt as often as I like at zero cost, and the strict citation rules cost me only time.
The whole chain is open. The data is the public GitHub API, the model is open-weight, and the scoring rules are readable code, so every sentence in a eulogy can be traced back to a link.
Where a closed model would be better: raw writing quality. A large hosted model would probably write livelier prose with fewer slips. But it would still need the same citation check, and it would put a server, a key and a bill between you and a repository's memorial.
The Spirit of It
DĂa de los Muertos is about the idea that people are not gone while someone still tells their stories. Open source works the same way. A repository is a trace of someone's evenings, their curiosity, their stubbornness with a bug at 2 AM, and most of those traces go quiet without anyone saying goodbye.
The Software Cemetery is my small ofrenda for them: an evidence-backed story for each repository, told with warmth, never with mockery, and always ending with an invitation instead of a verdict. Read the latest issues. Say hello to the maintainers. Maybe say thank you. Maybe bring flowers. 🌼
Prize Categories
- Best Use of Gemma: every Gemma-written eulogy comes from Gemma 3 running locally through Ollama, and a large part of this post is about keeping a small model honest with evidence ids and a code-level citation check.
- Best Use of Render: the live demo is deployed on Render as a FastAPI web service, with the build and start commands documented in the README.
Top comments (0)