This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
Somewhere in your package.json right now, there is probably a ghost.
Not a metaphor — a real, measurable kind of ghost. A package whose last release was four years ago. Whose maintainer answered their last issue in 2022. Whose repository still serves millions of downloads a week to people who haven't noticed it stopped breathing. Dependency abandonment is invisible: nothing breaks, nothing warns, nothing tells you the ground under your import statements went soft until the CVE drops or the API you depend on gets deprecated out from under you.
Revenant makes the invisible visible — and then it does something no dependency auditor has ever done.
Paste a package.json, requirements.txt, pyproject.toml, a public repo URL, or a single package name. Revenant resolves every dependency to its source repository, reads its vital signs — commit cadence, release gaps, archive status, deprecation flags, bus factor, issue-response latency, download and dependent curves — and computes a ghost score: the estimated probability that a project will be abandoned within the next 12 months. Every dependency lands in a band: Alive, Fading, Haunted, Departed — or Unknown, when the honest answer is "we couldn't find enough public signals."
Then, for the ones already gone, Revenant holds a funeral.
Every departed project gets a tombstone: a dignified epitaph written by an open-weight model, a cause of death backed by numbered, cited evidence, vital-sign meters showing exactly where the pulse flatlined, a score-contribution chart showing which signals drove the verdict — and an ofrenda, a three-tier altar where every recorded contributor burns as a candle, sized by the share of the project they carried. You can light a candle yourself.
You can also hold a seance: ask the spirit of request or node-sass what it did and how it ended. The spirit answers only from the project's own records — commits, releases, registry entries, docs — and when the evidence isn't there, it says "I don't remember that" instead of hallucinating.
And because grief without a plan is just sadness, Resurrection ranks the living successors and drafts a migration plan — deterministically, so it works with zero API keys — with a real manifest diff showing what to remove and what to adopt. Nothing is ever committed to your repo without explicit human approval; the "Open PR" button stays honestly disabled until GitHub sign-in is genuinely configured.
The Week 4 theme gave me two readings of "ghost in the machine," and I took both: the zombie dependencies haunting your dependency tree — and, in the spirit of Día de los Muertos, a graveyard built for honoring, not horror. The one rule hard-coded across the entire product: signals, not verdicts. A ghost score is a probability estimate, never an accusation. Maintainers owe nobody anything.
The headline finding from the shipped Graveyard Index: 27 of 180 of the most-downloaded npm + PyPI packages — 15% — already show Haunted-or-worse signals.
Demo
Live: https://revenantai-8hnl.onrender.com/ — no account, no key, public data only.
A tour worth five minutes:
- The Cementerio — the Graveyard Index: 180 real packages ranked by ghost risk, with a "Recently departed" strip, band filters with live counts, sorting, and search that still works as a plain GET form with JavaScript off
-
The tombstone of
request— one of the most-depended-on packages in npm history, deprecated in 2020. Full epitaph, vital signs, score breakdown, ofrenda, seance -
The tombstone of
react— a living project still gets a vitals page; the contrast is the point - Paste your own manifest on the home page — or hit "Try a sample package.json" to fill a manifest seeded with known-departed packages
- Arena — the same autopsy judged across open-weight models, with real precomputed bouts and latency bars; vote for the best eulogy
- Receipts and Science — every integration checked live and honestly reported; methodology and signal weights in the open
It also ships as a CLI that works with the internet switched off:
npx revenant-cli scan . --json # CI-friendly structured output
npx revenant-cli scan . --offline # bundled 180-package index, zero network
node cli/bin/revenant.js grave npm/left-pad # ASCII tombstone in your terminal
…and a GitHub Action that warns on PRs adding haunted or departed dependencies before they merge:
- uses: SayemR0018/revenantAI@main
Code
SayemR0018
/
revenantAI
Which of your dependencies are already ghosts? Ghost-risk predictions, tombstones, and resurrection plans for open-source projects.
👻 Revenant
Which of your dependencies are already ghosts?
Revenant predicts which open-source projects are about to die, holds a funeral for the ones that already did, and helps you resurrect your code with a living successor.
Two readings of "ghost in the machine" at once: zombie dependencies haunting your dependency tree — and, in the spirit of Día de los Muertos, an ofrenda that honors the projects (and people) that gave us so much before they went quiet.
Signals, not verdicts. A ghost score is a probability estimate, never an accusation. Maintainers owe nobody anything.
Live demo · Screenshots · What it does · How it works · Use cases · Quick start · Verified numbers
Live demo
| 🌐 Web app | https://revenantai-8hnl.onrender.com/ — no account needed, public data only |
| 📦 CLI | npx revenant-cli scan . |
| ⚙️ Action | uses: SayemR0018/revenantAI@main |
| 📄 License | MIT — LICENSE |
A brand-new checkout —…
MIT-licensed, fully auditable, and organized so a judge can walk the whole pipeline end to end:
-
lib/score.ts— the transparent heuristic scorer. Every point is attributed to a named signal; nothing is a black box unless TabPFN is live, and the model name is always recorded on the result -
lib/pipeline.ts,lib/tombstones.ts— scan orchestration and memorial assembly; a package that doesn't exist in its registry returns a real HTTP 404, never a fabricated tombstone -
mastra/— autopsy, seance, and resurrection agents + workflows + thepredictGhostScoretool -
ml/— the FastAPI TabPFN ghost-risk service, plus the Tinker LoRA dataset/training/eval scripts for the epitaph writer -
app/,components/— Next.js 16 App Router frontend: scan form with SSE progress, report, tombstone + ofrenda, Cementerio, Arena, Science, Receipts -
app/api/— scan, seance, resurrect, arena, badge SVG, and three Satori OG card routes (1200×630 PNGs for home, tombstones, and reports) -
cli/+action.yml— the offline-capable CLI and composite GitHub Action -
data/seed/— the 180-package index and 20 showcase tombstones, every byte generated by the real pipeline on 2026-10-30 -
temporal/—ExhumeWorkflowwith queryable progress and an honest in-process fallback -
receipts.json+/receipts— every integration checked live: 5 PASS, 14 SKIPPED, 0 FAIL. Missing credentials report SKIPPED with the fallback named — nothing is faked -
docs/WRITEUP_FACTS.md— the running log of real numbers, bugs, and decisions every claim in this post traces back to
How I Built It
The product path runs entirely on open weights and open data. That's an architectural commitment, not a slogan.
Signals. ecosyste.ms — open data, no key required — is the primary backbone resolving packages to repositories and exposing activity signals, enriched by the npm and PyPI registries and the GitHub API (a GITHUB_TOKEN raises limits 60→5,000/hr when configured).
Scoring. A TabPFN prior-data network — a foundation model for tabular prediction — runs inside a FastAPI service (ml/) and returns calibrated ghost-risk probabilities. When ML_SERVICE_URL isn't set, a fully transparent heuristic scorer takes over with per-signal point attribution — the same ScoredDep shape either way, labeled heuristic-v1 or tabpfn, so you always know which brain scored you and why.
Prose. Gemma 4 (gemma-4-31b-it with gemma-4-26b-a4b-it fallback, via Google AI Studio's OpenAI-compatible endpoint) writes dignified autopsies, answers seances grounded in retrieved corpus evidence, and competes in the Arena — the same autopsy run across models so visitors vote on the best eulogy. A Tinker LoRA on Qwen3 is wired as the epitaph writer; dataset, training, and eval scripts ship in ml/tinker/. When no model is configured, rule-based output takes over — labeled fallback-rules, never impersonating LLM output.
Orchestration. Mastra agents coordinate autopsy → seance → resurrection; a Temporal ExhumeWorkflow makes scans durable and queryable — and absent a Temporal server, the identical pipeline runs in-process while the app tells you exactly which mode it's in. Tiger/pgvector provides hybrid retrieval for the seance corpus; MongoDB Atlas persists reports, votes, and agent memory — with a local file store when neither is configured.
Frontend. Next.js 16 + React 19 + Tailwind 4, deployed on Render (blueprint ships web + worker + ML service + nightly index cron), with Sentry for agent tracing. The Día de los Muertos design system is hand-built — inline-SVG papel picado banners, marigold gradients, a candle-flicker animation that respects prefers-reduced-motion, and Satori-generated OG cards so every shared tombstone link unfurls like an ofrenda.
Verification. Vitest unit tests, an extended Playwright suite covering real flows (scan → report → tombstone → badge → 404), @axe-core/playwright audits — 0 violations across all 8 routes — and scrollWidth ≤ clientWidth asserted at 390px on every page. 16 screenshots in docs/screenshots/ are generated by a script, not hand-picked.
Honest build notes — the bugs are part of the story, all logged in WRITEUP_FACTS.md:
-
The 404 that lied. Next 16 commits outer
loading.tsxboundaries to200 OKbeforenotFound()executes — nonexistent packages rendered cheerful fake tombstones until I moved the existence check above the Suspense boundary. A fake tombstone is the one thing this product can never ship. -
The report that raced itself. A non-atomic
fs.writeFiletruncatedreports/<id>.jsonin the exact millisecond between scan completion and redirect —JSON.parse("")on a blank file. Fixed with a write-through map + atomic.tmprename. -
The model that moved.
gemma-3-27b-itsilently died on AI Studio — the endpoint now serves Gemma 4 and prepends<thought>reasoning blocks before JSON.lib/llm.tsstrips them, validates with Zod, and falls back cleanly. -
Satori's strictness.
next/ogrejects any multi-child div without explicitdisplay:flex— found by live smoke test, not typecheck, the hard way.
Why Does Open Innovation Matter?
A tool whose entire job is detecting abandonment cannot itself depend on a service that can be deprecated out from under it. That's not ideology — it's the product requirement, and open innovation is the only way to satisfy it.
-
Open weights make the product survivable.
revenant-cli scan . --offlineruns a real audit with the network cable unplugged, because Gemma, TabPFN, and a LoRA can be downloaded, fine-tuned, and run locally — no API key, no rate limit, no shutdown notice. A ghost detector that 404s when a vendor sunsets an endpoint would be a punchline. -
Open data makes the claims reproducible. ecosyste.ms publishes the underlying signal data openly — the Graveyard Index is regenerable by anyone with
npm run seed, not a number you have to take on faith. - Open source makes resurrection possible. When an open project dies, its corpse is inspectable — forks persist, archives persist, contributor records persist — which is exactly what lets Resurrection name a living successor with evidence. Dead closed services don't leave tombstones; they just return 404.
-
And open records are what make honoring possible. The ofrenda works because contribution history is public. The candles on
request's altar are real people with real commit counts — the whole memorial is built from data open source chose to share.
My Agent Session
This project was built inside a Devin agent session end to end — scaffold, pipeline, ML service, a twelve-task frontend polish pass, and verification. The session's real bug catches are logged in docs/WRITEUP_FACTS.md: the streaming-404 race, the file-store truncation, the Gemma-4 model migration, Satori's flexbox constraints, a vitest/@types/node version conflict, a Cache Components clash in Next 16, and an npm allow-scripts policy that killed the first scaffold.
The Spirit of It
The moment it landed for me was the ofrenda on request's tombstone.
request was one of the most-depended-on packages in npm history — deprecated in 2020 after eleven years, still pulled down millions of times a week. On its tombstone, its contributors aren't a JSON array. Each one is a candle on a three-tier altar — papel picado overhead, marigold petals on the steps — sized by their share of the commits, with their handle and a link. You can light one. The page doesn't joke about the maintainer who walked away. It says what the project gave the world, lists living successors for the practical, and offers ways to support the people still around.
That ethic is enforced in code, not just in copy:
- A package that doesn't exist returns HTTP 404 — it never gets a fabricated tombstone.
- A dependency with thin evidence renders a gray UNKNOWN band — never a reassuring green ALIVE.
- The seance says "I don't remember that" when the corpus runs out — grounded refusal is a feature, not a failure.
- Every epitaph is labeled with the model that wrote it —
gemma-4-31b-itorfallback-rules— so AI prose never impersonates itself. - The disabled "Open PR" button says "requires GitHub sign-in" instead of faking a write.
Fifteen percent of the packages we all depend on are already showing haunted-or-departed signals. The least a graveyard can do is tell the truth about who's buried there — and remember the people who built them.
Prize Categories
Integrated and working — PASS in receipts.json:
-
Gemma / open-weight models —
gemma-4-31b-it+gemma-4-26b-a4b-itwrite dignified autopsies, grounded seance answers, and Arena bouts - ecosyste.ms — open-data backbone for all package → repo resolution and activity signals
-
GitHub Copilot / GitHub Actions — the composite
revenant-action, CI, and nightly index workflows ship in-repo -
Mastra — autopsy, seance, and resurrection agents, workflows, and the
predictGhostScoretool -
Entire — provenance configuration tracked in-repo (
.entire/settings.json)
Integrated, key-gated — the code is real and shipped; status flips to PASS the moment the credential is set, and honestly reports SKIPPED until then: TabPFN (Prior Labs), Tinker (Thinking Machines LoRA), Temporal, MongoDB Atlas, Tiger Data, Sentry, Render, Auth0, DigitalOcean Gradient, Backboard, SerpApi, Browserbase, ElevenLabs, Ultramarine — see .env.example and the live /receipts page.
Maintainers: this tool honors your work. If a score ever reads as a verdict instead of a signal, that's a bug — file an issue.





Top comments (0)