DEV Community

Cover image for I built a coroner for dead software. It issues death certificates, and it refuses to lie.
Damilola Mustapha
Damilola Mustapha

Posted on

I built a coroner for dead software. It issues death certificates, and it refuses to 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

Every developer has a graveyard.

Mine is a GitHub account full of repos that stopped one day and never started again. A linter I was sure would take off. A "weekend" game engine. Three different note-taking apps, because apparently the first two taught me nothing. I don't delete any of them, because deleting would mean admitting something. So they just sit there with a last commit from some Tuesday, going quietly from green to grey.

So for Ghost in the Machine, I built the thing those repos deserve. A coroner.

What I Built

Autopsy of a Dead Project is a forensic pathology tool for software. You paste a GitHub URL, and a machine examines the body, says plainly what the project was, works out how it died, and issues a death certificate: cause of death, time since the last sign of life, a differential diagnosis, and the project's recovered last words. If the repo turns out to be alive, you get a certificate of LIFE instead, flatline still beating green.

I shipped it this week on purpose. It lands on Halloween night and the first hours of Día de los Muertos, and Día de los Muertos isn't about fear. It's about remembering the dead by name. The coroner doesn't mock your abandoned projects, it memorializes them, and it does it with a cause of death it can actually defend. Every certificate recovers what the project was, in plain words, before it ever says how it ended. You're meant to feel something reading it, the way you're meant to feel something at an ofrenda.

It's spooky, and it's a little sad, which felt exactly right.

The death certificate for bower

Demo

A 90-second autopsy, start to finish. Three real repos: one abandoned, one burned out, one still breathing.

Try it live: autopsy.132-145-100-81.sslip.io

Paste bower/bower, sindresorhus/caprine, or fastapi/fastapi for an instant cached verdict, or feed it one of your own dead repos and wait for the full cold autopsy.

Code

GitHub logo dmustapha / autopsy-of-a-dead-project

Open-source-AI post-mortem of a GitHub repo: features -> TabPFN classification -> grounded eulogy -> death certificate.

Autopsy of a Dead Project

Paste a GitHub repo URL. An open-weight AI performs a forensic autopsy, classifies how the project died, reads a grounded coroner's eulogy, and hands you an amber death certificate.

tests python license

Live: https://autopsy.132-145-100-81.sslip.io

Autopsy hero


What it is

A single-page FastAPI app that reads a GitHub repository's public history and answers one question: is this project alive, and if not, how did it die?

The flow, from one pasted URL:

  1. Extract: pull the repo's commit cadence, contributor spread, lifespan, and staleness from the GitHub API into six numeric features.
  2. Classify: a local open-weight tabular model sorts the project into one of five death modes: abandoned, burned_out, alive, completed, or pivoted.
  3. Narrate: a decentralized open-weight LLM writes a 120-200 word coroner's eulogy, grounded strictly in the evidence (it may evoke the story, but every factual claim is bound to a real metric).
  4. Certify: the verdict…

How I Built It

Two open-weight models do the forensics, and splitting the work between them is the whole design. One's a classifier. The other's a reader and a voice.

TabPFN is the core predictor. It's an open-weight tabular foundation model from Prior Labs, and instead of me training a classifier on my data, it does in-context learning: you hand it a small labelled corpus plus a new row, and in one forward pass it hands back a posterior, an actual probability distribution over the outcomes, not a single confident guess. The "row" is a 10-feature vector I pull from the GitHub API for any repo:

  • days since last commit
  • commit-cadence decay (how fast the heartbeat slowed)
  • lifespan in days
  • contributor count
  • bus factor
  • velocity ratio (recent activity over lifetime activity)
  • is archived
  • release recency
  • has releases
  • open-issue ratio

Ten numbers in, a distribution over six death modes out: abandoned, burned_out, pivoted, completed, alive, and insufficient_history. The verdict is TabPFN's output. Rip the model out and you're left with a heuristic rules page.

It doesn't work alone though, and that's on purpose. TabPFN sits in the middle of a wider prediction system: feature extraction feeds it, a language model settles its closest calls, and a grounding gate guards whatever's about to hit the page. The foundation model does the thinking. Everything around it is just there to protect the answer.

The reader and the voice is deepseek-v4.1-flash, an open-weight LLM I run through 0G Compute, a decentralized open-weight inference network. When TabPFN's top two causes are too close to call, it reads the actual commit messages and README and breaks the tie, but only when it's confident. And it writes the eulogy and recovers what the project was, always tied back to the evidence.

Does the foundation model actually earn its place?

Is TabPFN really better than the dumb thing, or is it just decoration?

So I ran a held-out eval. I've got a corpus of 117 hand-labelled repos, and I did leave-one-out cross validation: for each repo, train on the other 116, predict the one you held back, never let a repo see itself. Ran it for TabPFN and for an honest baseline, a standardized 1-nearest-neighbour over the exact same features, which is literally the fallback logic the app already ships with.

  • TabPFN, leave-one-out: 58.1%
  • 1-NN baseline, leave-one-out: 43.6%
  • 14.5 points clear, against a chance rate around 21% across five populated classes.

That gap is the entire reason to put a foundation model here instead of a lookup table. On a small, messy, hand-labelled corpus, in-context learning actually separates the hard calls, abandoned vs burned_out, completed vs abandoned, better than "find the nearest repo and copy its label."

One honest footnote, since the whole tool is about honesty. One feature (primary_language_freq) is encoded over the full corpus instead of strictly per fold. It's a minor leak, it's symmetric (both models get it), and it's conservative: take it out and the 1-NN baseline actually goes up to 45.3%, so it isn't padding TabPFN's win. The frequency encoding is full-corpus; the leave-one-out is strict everywhere else, and 58.1% clears the honest ceiling either way.

The rest of the stack is deliberately boring so the ideas can be loud: Python, FastAPI and uvicorn, a Jinja2 template, and vanilla JS on a <canvas> for the certificate itself (the flatline animation, the wax seal, the guilloche watermark, no framework bloat). 68 tests green.

Why Does Open Innovation Matter?

The whole pitch of this thing is a verdict you can trust. It stamps "cause of death" on your side projects, so the one thing it can't be is a black box. And a closed classifier API would make it exactly that. If some hosted model decided your repo was "abandoned," I couldn't show you the probabilities behind the call, couldn't prove it beats a dumb baseline on a held-out test, couldn't even promise the same input gives the same answer next quarter. The honesty I'm selling would collapse into a logo on a mystery.

Open weights fix that. TabPFN runs locally, on my own box, so every verdict comes from weights I can open up, run offline, pin to a version, and call for free, as many times as I want. No vendor's sitting in the loop deciding how your project died. Nothing to rate-limit, nothing to deprecate, nothing quietly changing the answer between demos. That's where open genuinely beat closed for me: a closed model could've written the eulogy, but it could never have handed me the proof, the inspectable posterior and the held-out number that make the verdict defensible instead of just confident.

There's a second reason, and it fits the theme a little too well. A tool built on a closed model is one shutdown email away from becoming another dead project itself. The coroner runs on open weights precisely so a vendor can't abandon it the way we abandoned the repos it examines. The graveyard keeper should outlive the graveyard.

I'll be exact about one thing, because a coroner that fudges its own architecture has no business lecturing anyone about honesty. TabPFN runs local. The narration and tie-breaking run on 0G Compute, which is a network call, not a local process. There's a fully-local fallback that points the same code at a local Ollama model, but the live demo isn't running it, so I'm not going to pretend it is. Are the weights open end to end? Yes. Does nothing phone home? Not for the live service, and the certificate says so. Every result carries an engine label (classified by TabPFN, tabpfn + llm · adjudicated, or a plain rules fallback), and the narration badge reads "evidence read by deepseek-v4.1-flash · 0G Compute", pulled from the real engine field, never hardcoded. Nothing hides behind a generic "AI says."

The Spirit of It

Here's the design decision I think actually makes this worth shipping.

A eulogy is generative text, and generative text hallucinates. A coroner that invents a cause of death isn't a coroner, it's a liar with nice handwriting. So between the model and the certificate there's a grounding gate. Before any eulogy or recovered summary reaches the card, I check that its claims trace back to the real evidence, the actual commit record, the real README. If the prose drifts into something the data doesn't support, the gate throws it out, and the certificate falls back to a strictly factual coroner that says so out loud.

The tool would rather tell you "I couldn't ground this" than narrate a death it can't defend. That's not a bug I'm apologizing for, it's the feature.

You can watch it hold the line across the three repos in the demo.

bower/bower came back ABANDONED, and the differential is honest about its own doubt: abandoned 59%, burned_out 35%, completed 3%, pivoted 2%, alive basically nothing. It recovered "Bower is a package manager for the web," which is correct and plain. There were no defensible last words, so the death note stayed empty. It had nothing honest to quote, so it quoted nothing. Honestly, I think that blank space is the most trustworthy thing on the page.

sindresorhus/caprine came back BURNED_OUT, and the recovered last words are almost too on the nose: "Caprine is feature complete." That's the maintainer, in their own README, signing their own certificate. It only shows up because it passed the grounding check against the real repo. I didn't write that line. The dead did.

fastapi/fastapi came back a certificate of LIFE. Flatline still green. The coroner's just as willing to tell you a project's alive and you're the one who walked away. That reversal is the moment this stopped being a gimmick for me. It's not a death stamp, it reads the signal honestly either way.

fastapi, a certificate of life

And since a tool about honesty can't go quiet in the one place honesty costs something, here's what it's not. The corpus is 117 rows, hand-labelled by me, so it's my little graveyard, not the universe of software. The six death modes are judgment calls; "burned out" vs "abandoned" is sometimes a story I'm choosing to tell about the numbers, and I believe the stories, but they're still stories. And it's slow on a cold case: a repo it's never seen means two live model calls plus a cold load, a couple of minutes, where a cached verdict comes back in under two seconds. I'd rather be honest and slow than fast and made up.

None of that makes it useless. It makes it a forensic estimate that knows it's an estimate, which, for something stamping "cause of death" on your side projects, is exactly the posture I want.

My graveyard's still full. The difference is every stone has a cause of death on it now, and I believe every one.

Go autopsy your own. Paste your proudest dead repo and see how it died. Or find out, maybe a little uncomfortably, that it's still breathing and you're the one who walked away.

Prize Categories

Best Use of TabPFN. TabPFN is the beating heart of this project, not a bolt-on. It's the open-weight tabular foundation model behind every verdict, used the way Prior Labs recommends: as the core predictor inside a wider prediction system (feature extraction, LLM tie-breaking on the close calls, and a grounding gate around the output). And I did the thing the category actually asks for, measured it against a baseline on a real held-out test: 58.1% vs 43.6%, a 14.5-point win on leave-one-out across 117 repos.

Top comments (0)