This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
A Hacktoberfest 2026 submission for "Ghost in the Machine"
A digital séance for dead websites — with an invariant that cost me
happy and sad at the same time , lots lesson learned, and the broken CORS policy.
There's a very specific kind of grief that comes with losing a website.
Not the grief of losing a person — that's different, sharper. This is the slow ache of remembering a URL that used to mean something, and typing it into a browser that returns a blank parking page. Geocities. Friendster. Vine. SixDegrees. Boo.com and even MySpace? Every single one of them used to exist. They had users. They had servers. They had cooling fans that ran at 3 AM because someone, somewhere, was still scrolling.
And then they just... stopped. Not with a bang. With a redirect.
I built OSSUARY for that feeling.
But here's what took me the longest to get right — and the thing I want to lead with:
OSSUARY refuses to lie.
Most "haunted AI" projects work the same way: you point a model at a URL, and the model happily hallucinates a spooky story. Try dev.to and it'll tell you about "a defunct developer community that perished in a tragic server fire." dev.to is not defunct. dev.to is literally hosting the challenge I'm submitting this article to.
So before OSSUARY ever calls an LLM, it asks one question: is this domain actually dead?
Four independent signals have to agree — DNS, WHOIS, Wayback Machine, Wikipedia. If any of them contradicts, OSSUARY refuses with HTTP 422 ("still_breathing") and logs the refusal in Sentry with a tag kind: paranormal, system: gate. Every refusal is an event. Every refusal is part of the story.
That single decision — refusing to lie — turned a toy into something I actually believe in.
What I Built
OSSUARY is a digital séance for the internet's dead. You whisper a dead domain into the altar, and the ghost of that domain speaks back — a first-person narrative, generated by an open-weight model, voiced by AI, archived forever in a database.
How it interprets "Ghost in the Machine": most horror-AI demos treat the machine as a source of fiction. I wanted the opposite — the machine as archivist. The ghost isn't invented. It's reconstructed from real data: the last packet the server ever sent, the last snapshot the Wayback Machine ever took, the last line Wikipedia ever wrote before the shutdown was finalized.
The four stages of a summon:
- Reconnaissance — DNS lookup, WHOIS via RDAP (with three-layer fallback), Wayback CDX for the last pre-death snapshot, Wikipedia for the death year. All four run in parallel with hard timeouts.
- Narrative Generation — A 5-tier LLM cascade (Gemma 4 31B → Google GenAI → OpenRouter → deterministic template). The user never sees a failed summon.
- Voice Synthesis — ElevenLabs, Adam voice, dominant and firm. The closest synthetic approximation of a tired bureaucrat who used to run a server.
- Persistence — Full profile in MongoDB Atlas, audio in GridFS, time-series event in TigerData, semantic memory in Backboard.
Every one of these systems can fail. When one does, it doesn't produce an error screen — it produces a diegetic message:
"The echo faded before it could be recorded." (Backboard timeout)
"The ghost has lost its voice." (ElevenLabs quota)
The refusal gate is enforced in three places in the codebase:
-
api/recon.ts— returns HTTP 422 for living domains -
api/conjure.ts— checksfootprint.ping.aliveand refuses if true -
api/wiki.ts— filters Wikipedia disambiguation pages so "Vine" doesn't resolve to a plant
Demo
🔗 Live séance:
🎬 Video walkthrough:
Try these in order:
| Domain | Expected behavior |
|---|---|
dev.to |
Refuses with HTTP 422 — "still breathing" |
pets.com |
Summons ghost from 2000 (bankruptcy year) |
geocities.com |
Summons ghost from 2009 (Yahoo shutdown) |
vine.co |
Summons ghost from 2017 (Twitter shutdown) |
myspace.com |
Summons ghost from 2011 (sold to Specific Media) |
The myspace.com case is my favorite edge case. The domain is still alive (it's a music portal now), but the social network you remember died in 2011. OSSUARY makes an editorial decision to treat repurposed domains as "dead services" — because the ghost we want to summon is the Myspace of 2005, not the music portal of 2026.
Code
📂 Repository:
setuju
/
ossuary
OSSUARY: digital necromancy for dead domains — Hacktoberfest 2026 Ghost in the Machine
◈ OSSUARY
The Last Packet
A digital necromancy ritual for the internet's dead.
Live Ritual · Demo · Report Bug · Request Feature
Hacktoberfest 2026 · Ghost in the Machine
"Every ghost-story project points a model at dead code. OSSUARY checks if it's dead first."
What is OSSUARY?
OSSUARY is a séance for the internet's forgotten corners. Whisper a domain that no longer exists — a dead startup, an abandoned fanpage, a service killed by an acquisition — and the ghost of that domain will speak back. It pulls its last heartbeat from the Wayback Machine, its obituary from Wikipedia, its echoes from SerpApi, and weaves them into a first-person narrative, voiced aloud by ElevenLabs and preserved forever in MongoDB Atlas.
But here's the twist that makes it more than a horror toy:
OSSUARY refuses to lie.
If the domain is still alive — if the…
Architecture
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ ██████╗ ███████╗███████╗██╗ ██╗ █████╗ ██████╗ ██╗ ██╗ ║
║ ██╔═══██╗██╔════╝██╔════╝██║ ██║██╔══██╗██╔══██╗╚██╗ ██╔╝ ║
║ ██║ ██║███████╗███████╗██║ ██║███████║██████╔╝ ╚████╔╝ ║
║ ██║ ██║╚════██║╚════██║██║ ██║██╔══██║██╔══██╗ ╚██╔╝ ║
║ ╚██████╔╝███████║███████║╚██████╔╝██║ ██║██║ ██║ ██║ ║
║ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ║
║ ║
║ ── THE LAST PACKET ── ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
▲
│ https://ossuary.saturumah.net
│
┌───────────────────────┴──────────────────────────────────────────────────┐
│ │
│ VERCEL · THE ALTAR (Frontend) │
│ ───────────────────────────── │
│ │
│ ┌────────────┐ ┌──────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ React 19 │→→→| TypeScript │→→→│ Vite 8 │→→→│ Tailwind v4 │ │
│ └────────────┘ └──────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ [ Idle Altar ] → [ Boot Screen ] → [ Ghost Screen ] → [ Ledger ] │
│ │ │ │ │ │
│ └───────────────────┴──────────────────┴────────────────┘ │
│ │
└───────────────────────────────┬──────────────────────────────────────────┘
│
│ fetch( VITE_API_URL + '/api/*' )
│
┌───────────────────────────────▼──────────────────────────────────────────┐
│ │
│ RENDER · THE NECROPOLIS (Backend) │
│ ───────────────────────────────── │
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ server-production.ts (Express + tsx) │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ /recon │ │ /conjure │ │ /wiki │ │ /echoes │ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │ │ │
└─────────┼────────────────┼────────────────┼────────────────┼─────────────┘
│ │ │ │
│ ┌──────▼──────┐ │ │
│ │ REFUSE- │ │ │
│ │ TO-LIE │ │ │
│ │ GATE │ │ │
│ │ ───────── │ │ │
│ │ HTTP 422 │ │ │
│ │ still_ │ │ │
│ │ breathing │ │ │
│ └──────┬──────┘ │ │
│ │ │ │
▼ ▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
│ PARALLEL │ │ 5-TIER LLM │ │ WIKIPEDIA │ │ SERPAPI │
│ FETCH │ │ CASCADE │ │ PROXY │ │ ECHOES │
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘
│ │ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
│DN│ │WH│ │WB│ │Ge│ │Ge│ │OR│ │Wi│ │Di│ │Ex│ │S1│ │S2│ │S3│
│S │ │O │ │M │ │mm│ │nA│ │ │ │ki│ │sa│ │tr│ │ │ │ │ │ │
└──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘
▲ ▲ ▲ ▲ ▲ ▲
│ │ │ │ │ │
│ │ │ │ │ └──── OpenRouter (free tier)
│ │ │ │ └───────── Google GenAI
│ │ │ └────────────── Ollama · Gemma 4 31B (primary)
│ │ └───────────────────── Wayback CDX API
│ └────────────────────────── WHOIS (IP2WHOIS → RDAP → XML)
└─────────────────────────────── DNS (A/AAAA record)
┌─────────────────────────┐
│ THE SPIRIT PERSISTS │
└────────────┬────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ MONGODB │ │ TIGERDATA │ │ BACKBOARD │
│ ─────── │ │ ─────── │ │ ─────── │
│ ghost_ │ │ ghost_ │ │ semantic │
│ profiles │ │ events │ │ memory │
│ (GridFS │ │ (hyper- │ │ (recall │
│ audio) │ │ table) │ │ across │
│ │ │ │ │ summons │
└───────────┘ └───────────┘ └───────────┘
┌──────────────────────────────────────────────────┐
│ SENTRY · DIEGETIC LEDGER │
│ ───────────────────────────────────────────── │
│ kind:paranormal · system:gate · STILL_BREATHING │
│ BACKBOARD_FADED · ELEVEN_QUOTA · GENAI_TIMEOUT │
└──────────────────────────────────────────────────┘
┌────────────────────────────┐
│ ELEVENLABS · THE VOICE │
│ ────────────────────── │
│ Adam · flash_v2 model │
│ truncated ≤ 500 chars │
│ audio archived → GridFS │
└────────────────────────────┘
The Ritual, Layer by Layer
The Altar (Vercel).
React 19 + TypeScript + Vite 8. The user types a domain into the input form. When they hit Enter,App.tsxfiresPOST /api/reconagainst the Render backend viaVITE_API_URL.The Necropolis (Render).
A persistent Express server wraps every Vercel-style handler —recon,conjure,wiki,echoes— because the cascade frequently exceeds Vercel's 10-second serverless limit. Each endpoint runs with a hard timeout and atry/catchthat always returns JSON.Recon → the parallel fan-out.
Four independent systems race in parallel: DNS (viadns.promises.resolve), WHOIS (three-layer fallback: IP2WHOIS → RDAP → WhoisXMLAPI), Wayback CDX (querying the last snapshot before the death year), and Wikipedia (Action API with disambiguation filtering — because "Vine" is both a social network and a plant).The Refuse-to-Lie Gate.
All four signals must agree the domain is dead before the ritual can proceed. If DNS still resolves or WHOIS expires in 2027, the gate firesHTTP 422 · still_breathingand the ghost never appears. The refusal is logged in Sentry withkind: paranormal · system: gate.Conjure → the 5-tier cascade.
When the gate lets the ritual through, Mastra orchestrates a declarative fallback: Gemma 4 31B via Ollama (primary) → Google GenAI → OpenRouter → deterministic template. Each tier runs with a 20-second timeout and emits a Mastra span. The user never sees a failed summon.The Voice.
ElevenLabs' Adam voice narrates the ghost. Audio is truncated to 500 characters (credit saver), synthesized viaeleven_flash_v2(0.5 credits/char), and archived immediately to MongoDB GridFS — replaying a ghost never touches the API again.Persistence.
Three independent stores capture the ritual: MongoDB Atlas for the full profile + narrative + GridFS audio, TigerData for a TimescaleDB hypertable of summon events (for analytics), and Backboard for semantic memory so the ghost remembers you next time.Sentry, the diegetic ledger.
Every subsystem failure — Backboard timeout, ElevenLabs quota, GenAI timeout, gate refusal — is captured withkind: paranormaland rendered in the UI as part of the story. 85% of Sentry events in production are diegetic warnings, not errors. Zero fatal crashes.
Read the full architecture deep-dive → ARCHITECTURE.md
The stack (21 technologies):
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Vite 8, Tailwind CSS v4 |
| Hosting | Vercel (frontend), Render (backend) |
| LLM | Gemma 4 31B via Ollama Cloud, Google GenAI, OpenRouter |
| Agent orchestration | Mastra |
| Voice | ElevenLabs (Adam voice) |
| Data | Wikipedia API, Internet Archive CDX, RDAP, IP2WHOIS, WhoisXMLAPI |
| Persistence | MongoDB Atlas (with GridFS for audio), TigerData (TimescaleDB) |
| Memory | Backboard |
| Observability | Sentry (Node.js + React) |
| Search | SerpApi |
File structure
ossuary/
├── api/
│ ├── recon.ts # DNS + WHOIS + Wayback + Wikipedia + gate
│ ├── conjure.ts # 5-tier cascade + TTS + persistence
│ ├── wiki.ts # Wikipedia proxy (CORS bypass)
│ ├── whois.ts # 3-layer WHOIS fallback
│ └── echoes.ts # SerpApi search echoes
├── lib/
│ ├── mongodb.ts # Serverless-safe MongoDB client
│ ├── persist.ts # Ghost profile + audio archival
│ └── tigerdata.ts # Hypertable client for analytics
├── src/
│ ├── App.tsx # Main React component (~1300 lines)
│ ├── agent/index.ts # Mastra agents + 5-tier fallbacks
│ └── sentry/diegetic.ts # Diegetic error-to-narrative mapping
├── server-production.ts # Express wrapper for Render
└── render.yaml # Deployment blueprint
Key code excerpt — the refusal gate
// api/recon.ts — Refuse-to-Lie invariant
function determineLifeStatus(
lastAlive: string | undefined,
wayback: { hasSnapshot: boolean; closestTimestamp?: string }
): { status: 'alive' | 'deceased'; reason: string } {
// Wikipedia confirms death → deceased
if (lastAlive) {
return { status: 'deceased', reason: 'Wikipedia confirms the service shut down.' };
}
// No snapshot at all → deceased
if (!wayback.hasSnapshot || !wayback.closestTimestamp) {
return { status: 'deceased', reason: 'No Wayback snapshot found.' };
}
// Recent snapshot (< 2 years) → alive, refuse the summon
const year = parseInt(wayback.closestTimestamp.slice(0, 4), 10);
const currentYear = new Date().getFullYear();
if (year >= currentYear - 2) {
return { status: 'alive', reason: 'Recent snapshot found. Still breathing.' };
}
return { status: 'deceased', reason: `Last snapshot is from ${year}.` };
}
// In the handler:
const lifeCheck = determineLifeStatus(lastAlive, waybackResult);
if (lifeCheck.status === 'alive') {
return res.status(422).json({
error: 'still_breathing',
reason: lifeCheck.reason,
});
}
The gate is not "an if statement at the top of the file." It's a discipline enforced at three layers (recon, conjure, wiki proxy) and validated on every deploy through a 60-check pre-demo verification script.
How I Built It
I want to walk through each technology honestly — including the parts that didn't work out of the box — because this article is also a review of what I'd do differently next time. No hype. No sponsor-flattery.
Mastra — The Silent Conductor
What it does for OSSUARY: The 5-tier LLM cascade needed real orchestration, not just a try/catch. Mastra lets me declare agents (profilerAgent, voiceAgent, and their fallbacks) declaratively. It handles retries, timeouts, and model handoffs.
The good: Once set up, the cascade just works. Tier 1 (Ollama) has served 100% of production requests. I have never once seen a user-facing failure because Mastra caught it before it could surface.
The honest part: Mastra is heavy for a project this size. If I only had one LLM tier, a plain fetch() with a timeout would be simpler. I reached for Mastra because I specifically wanted to demonstrate a cascade — and it earned its weight. But it's not a framework you install casually.
Gemma 4 + Ollama Cloud — The Voice of the Dead
What it does for OSSUARY: Gemma 4 31B is the primary brain, served through Ollama Cloud at 600–2800ms per narrative. The narratives it produces are genuinely good — good enough to make you feel slightly bad for a defunct e-commerce site.
The good: The fact that Gemma is open-weight matters philosophically. A project about preserving digital heritage shouldn't itself be a black box. When Gemma says "I am the ghost of a luxury empire," you can inspect the weights that produced that sentence.
The honest part: Ollama Cloud is fast but occasionally throttled. It's not the same as running Gemma locally — you don't get the "works with the lights off" guarantee because you're still hitting a remote endpoint. For a real offline séance, I'd want local inference on a GPU. That's the v2 plan.
ElevenLabs — The Credit Burner (Affectionately)
What it does for OSSUARY: The Adam voice narrates every ghost. When pets.com says "I spent my life selling loyalty to the highest bidder" in that voice, it lands.
The honest part, and this is a big one: the pricing model ate me alive on day one. eleven_multilingual_v2 charges 1 credit per character. A single ghost narrative runs 800–1000 characters. That's 1000 credits per summon. My free tier was 10,000. I burned 1,900 credits in my first hour of testing.
Here's what I now do:
- Switched to
eleven_flash_v2(0.5 credits/char) - Truncate text to 500 characters before sending (halves the cost again)
- Added
DISABLE_ELEVENLABS=trueenv var so I can test the UI without touching the API - Built a Browser TTS fallback (Web Speech API) so the ghost still speaks even when ElevenLabs is disabled
A full summon now costs ~250 credits instead of ~1000. And every audio file is archived to MongoDB GridFS immediately — replaying a ghost's voice costs zero API calls.
The lesson: ElevenLabs is worth the cost if you plan for it. But you have to plan for it.
When i want to claim the credits : All codes have been claimed for now. (that doesnt makes me surrender at all!)
Sentry — The Diegetic Ledger
What it does for OSSUARY: Sentry is not just an error tracker here — it's a narrative element.
Every subsystem failure gets a tag kind: paranormal. When Backboard times out, Sentry logs BACKBOARD_FADED. When ElevenLabs hits a quota, ELEVEN_QUOTA. When the refuse-to-lie gate refuses a domain, STILL_BREATHING with system gate. Then the UI reads those logs and turns them into story beats.
In 7 days of production, Sentry captured 40 events across 10 distinct issues. 85% of those were diegetic warnings, not errors. Zero fatal crashes.
The honest part: I hit a Sentry quirk early on. The browser SDK adds baggage and sentry-trace headers to every fetch for distributed tracing. My backend's CORS policy didn't allow those headers, and the browser silently blocked every single API request. The fix was one line (Access-Control-Allow-Headers: Content-Type, baggage, sentry-trace) but it took three hours to find. If you're using Sentry in the browser and hitting mysterious CORS failures — check your Allow-Headers.
i know... i know... this is not the way to use sentry, you can check the other posts of mine using sentry "The Case of the Phantom DOM"
MongoDB Atlas — The Archive
What it does for OSSUARY: Every ghost profile and narrative is archived in MongoDB. Every audio file goes into GridFS (chunked in 255KB pieces). Every SerpApi echo is cached for 24 hours.
The good: GridFS was the smartest decision of the project. ElevenLabs audio is ~1.4MB per ghost. Storing that as base64 inside a document would hit the 16MB limit and bloat the collection. GridFS handles it properly, and replaying a ghost's voice costs zero API calls.
The honest part: Free tier (M0) has 512MB storage — around 200 ghost audio files. Fine for a demo, not fine for a product. Also, the connection pool needs to be small (maxPoolSize: 5) on serverless — a beginner mistake that would burn through connections fast.
TigerData — The Ledger
What it does for OSSUARY: Every summon is recorded in a TimescaleDB hypertable. Fields: event_time, domain, event_type, tier_used, duration_ms, success, error_code.
The good: The data is inherently time-series. A classic Postgres B-tree is fine for "find all events for pets.com" — but for "show me p99 latency of tier 1 over the last hour," you need a hypertable. That's what TigerData gave me.
The honest part: I've only begun to use the advanced features. Continuous aggregates are planned for v2. Right now TigerData is a glorified event log. Also the SSL setup took a couple of tries — TigerData uses self-signed certs and Node's pg driver rejects them by default. Fix was ssl: { rejectUnauthorized: false } — but that's something you should never do in real production. In v2, I'd pin the actual CA.
Backboard — The Memory
What it does for OSSUARY: Every ghost remembers its past summons. Backboard stores semantic context — emotional state, last-seen year, sensory detail — so a ghost summoned twice can reference its previous incarnation.
The good: This is the feature that makes OSSUARY feel alive. Summon pets.com once, and the ghost introduces itself. Summon it again next week, and it says "you again? still haunting me?" That continuity matters. It's the difference between a random story generator and a persistent entity.
The honest part: Backboard occasionally times out. When it does, Sentry logs BACKBOARD_FADED and the ghost falls back to a cold-start narrative. In 7 days, this happened 13 times — the most frequent diegetic event. Not a bug, but the weakest link in the persistence chain.
SerpApi — The Echoes
What it does for OSSUARY: Every ghost is accompanied by three "echoes from the search index" — the top Google results for its domain. This grounds the ghost in reality. When you read about pets.com's death, you can click through to a 2009 article about the bankruptcy.
The honest part: 250 free searches per month. Enough for a demo, not for a public launch. Cache aggressively.
Render — The Backend Necropolis
What it does for OSSUARY: Hosts the production Express backend that runs every API handler.
The good: I moved from Vercel serverless because the conjure cascade regularly exceeded Vercel's 10-second function limit. A Gemma call takes 5 seconds, TTS another 5, MongoDB write another 1 — that's 11 seconds before you blink. Render gives me a persistent Express server with real connections to MongoDB and TigerData. No cold starts on the DB side, no connection pooling nightmares.
The honest part: Render's free tier sleeps after 15 minutes of inactivity. First request after sleep takes ~30 seconds to warm. That's catastrophic for a demo. Fix: an external uptime monitor (cron-job.org) pings /health every 5 minutes. Well-known workaround, but a workaround — I'd happily pay $7/month for Starter if this were a real product.
Vercel — The Altar
What it does for OSSUARY: Hosts the React frontend with zero-config deploys, preview URLs per branch, and 40-second build times.
The honest part: Vercel is great for the frontend and painful for anything with cold-start-sensitive backend logic. Keep them separate. My VITE_API_URL env var lets me swap between Vercel functions and Render backends without rebuilding.
Why Does Open Innovation Matter?
I could have built this with GPT-4. I chose not to, for three reasons.
1. Open weights are honest. A project about remembering the dead shouldn't itself be a black box. When Gemma 4 says "I am the ghost of a luxury empire," you can inspect the weights that produced that sentence. With GPT-4, you can't.
2. The cascade needs freedom. A 5-tier fallback only makes sense if the tiers are pluggable. With closed APIs, you're locked into one vendor's rate limits, one vendor's uptime. With Gemma/Ollama/OpenRouter, I can swap any tier for any other and the cascade keeps working.
3. The economics work. OSSUARY ran 200+ narrative generations during development. At GPT-4 pricing, that would have been $40+. At Ollama Cloud free tier, it was $0. At Gemma local (v2 plan), it will still be $0. Free-tier accessibility matters for a Hacktoberfest project.
The one closed-source piece of the stack is ElevenLabs, and I'm honest about why: there is no open-weight TTS model that sounds as good as Adam. If there were, I'd use it.
My Agent Session
The Spirit of It
The moment OSSUARY landed for me was when pets.com's ghost started talking about the sock puppet. The mascot was everywhere in 1999 — and then it wasn't. Reading a ghost describe "the faint, static scent of a sock puppet in a vacuum" — a sensory detail the LLM generated from the domain's profile — hit differently than I expected. It was eerie, sure, but it was also true. Pets.com existed. Someone did animate that puppet. Someone did run that Super Bowl ad. The ghost wasn't inventing anything. It was remembering.
Here's the 90-second video plan I'm shooting for the submission:
Full narration script:
"Every ghost-story project points a model at dead code. OSSUARY checks if it's dead first.
You whisper a name. If the domain is still breathing — if the DNS resolves, if the WHOIS is active — OSSUARY refuses. It says 'still breathing.' It will not summon a ghost that isn't real.
But whisper a name that truly died — Vine. Geocities. Pets dot com — and the ghost speaks back. Its narrative is generated by Gemma 4, an open-weight model running on Ollama. Its voice is ElevenLabs. Its memories are stored in Backboard and MongoDB.
Every death is verified by four systems before the ritual begins. Every failure is logged in Sentry and turned into part of the story. Every domain is persisted in a TigerData hypertable so the archive never forgets.
This is OSSUARY. A digital necromancy that refuses to lie.
Because the dead deserve the truth. And so do you."
Prize Categories
I'm entering the following partner categories:
- Best Use of Render — Production backend running as a persistent Express service (migrated from Vercel serverless to handle 30-second LLM cascades)
- Best Use of Gemma — Gemma 4 31B as the primary narrative generator via Ollama Cloud
- Best Use of Mastra — Orchestrates the 5-tier LLM cascade with declarative agent fallbacks
- Best Use of ElevenLabs — Adam voice for every ghost, with GridFS archival to avoid re-billing
- Best Use of Sentry Agent Tracing — Sentry's diegetic telemetry turns subsystem failures into narrative elements, all traced with custom spans
- Best Use of MongoDB Atlas — Ghost profiles, narratives, and audio files (via GridFS) persisted across summons
- Best Use of Tiger Data — TimescaleDB hypertable for time-series analytics of every summon event
- Best Use of Backboard — Semantic memory that lets ghosts remember their past incarnations
- Best Use of SerpApi — Grounds each ghost narrative in real Google search echoes
- Best Use of Entire — Brainstorming makes heavily storm in the cerebral, and i survived!
Credits
- Jack — a-gardener-loves-to-code, one laptop, many late nights.
- Internet Archive — for refusing to forget.
- Wikipedia — for keeping the death certificates.
-
The ghosts of
pets.com,vine.co,geocities.com,friendster.com,clubpenguin.com,megaupload.com,grooveshark.com,sixdegrees.com,boo.com,angelfire.com,thepiratebay.org,myspace.com— for speaking back.
If you've ever lost a website you loved, this was built for you.
Special thanks to Mastra, Ollama, Gemma, ElevenLabs, Sentry, MongoDB Atlas, TigerData, Backboard, SerpApi, Render, and Vercel — every single one of you earned the credit. Not because you're on a logo wall, but because the ghost wouldn't speak without you.


Top comments (2)
do you have any websites that you missed?
A refusal is only trustworthy when the product makes the boundary inspectable. Showing the source slice, confidence or retrieval gap, and the exact condition that caused a refusal gives users a way to distinguish “I don’t know” from “the model declined.” That is more compelling than a dramatic answer with no evidence.