This is a submission for the Sanity Challenge, Path Two: Vibe-Code Something Strange
What I Built
Dead Software Library β a haunted cemetery for discontinued software, inspired by Dead Poets Society. Just as the film's Welton boys kept poetry alive by gathering in secret to read verse for dead poets, this graveyard keeps dead software alive the same way β through remembrance. Adobe Flash, Vine, Google Reader, Windows Phoneβ¦ each gets a tombstone with a soul meter, flowers, epitaphs, and eulogies. Leave a flower and a ghostwriter agent reviews your tribute; spam gets rejected, good memories get sanctified and the soul rises +5.
- Graveyard /: tombstone grid with decay shaders tied to vitalityScore. Search, cause-of-death filter, 4 sorts, live stats pills. Reads from Sanity, so souls and flowers always stay in sync.
- Detail modal: click any stone β eulogies, successor, inline tribute box. Be the first mourner.
- Bury new software: anyone can bury a new entry (name, born/died years, cause, epitaph, successor). No login needed.
- Simple steps for each tribute: submitted -> ghostwriter_review -> sanctified or rejected. Spam (links, "buy now", "crypto giveaway") is rejected before anything is written. A decay tick fades souls daily: fading -> ghost -> haunting -> peaceful_rest.
- Works even without setup: if Sanity keys are missing, the server falls back to local db.json. Add keys and it shows real live data.
Demo
- Website Link: https://dead-software-library-web.vercel.app/
Local run (verified):
cd dead-software-librarynode server.js
http://localhost:3001 (graveyard β "backend: sanity" in /api/health)
GET /api/health, /api/corpses, /api/eulogies?project=flash
Reset data anytime: node scripts/seed-sanity.js (re-seeds 18 + 3 canonical docs).
No login required. Zero npm dependencies β Node 18+ only. Judges can click immediately (local fallback) or with live Sanity data.
Suggested video flow (60s): graveyard overview -> search/filter -> open Flash detail -> lay flower with memory submitted -> ghostwriter_review -> sanctified, soul +5 -> spam tribute -> rejected -> bury new software -> exorcism to peaceful_rest.
Code
Code: https://github.com/Harish-1511/Dead-Software-Library
dead-software-library/
schemas/deceasedProject.ts # name, born/died years, cause list, status, vitalityScore, flowersLeft, epitaph, eulogies refs
schemas/eulogy.ts # author, memory (max 500), project ref, state, poeticInscription
sanity/decay-workflow.ts # ghostwriterReview + decayTick + statusFor + approvePatch (pure logic)
sanity/SeanceDashboard.tsx # custom Studio tool β Graveyard Radar, vitality colors + Flower/Exorcism patches
sanity/ghostwriter-api.example.js # webhook shape: eulogy.create -> POST review -> ghostwriter_review
sanity/sanity.client.js # server-side Sanity client, token never leaves the server
server.js # Sanity-first REST (tribute/bury/exorcise/decay-tick) + static host + .env loader
scripts/seed-sanity.js # idempotent createOrReplace seed from web/data.js
web/app.js # graveyard UI, backend sync with localStorage fallback
web/data.js # 18 real dead-software seeds + 3 eulogies
SUBMISSION.md # full challenge writeup with verification table
My Build Process
IDE: OpenCode + Muse Spark.
Prompt that worked: "Sanity-first REST backend, zero npm deps, GROQ reads + patch mutations with local db.json fallback" β got all CRUD paths against the Content Lake in one shot (server.js), verified with "source": "sanity" in every write response.
Prompt that failed: naive JSON.parse of web/data.js for seeding β broke on apostrophes/quotes in epitaphs. Course-correct: evaluate the seed file in a sandbox and use createOrReplace mutations (scripts/seed-sanity.js), idempotent so judges can reset anytime.
Stuck: token alone doesn't reveal the project β called the Sanity management API with the key, discovered project s2icbb2m + production dataset, then flipped the backend from local-first to Sanity-first. Honest trade-off documented in repo: vanilla JS instead of Next.js/Astro so judges run one command with zero install; the useQuery swap point is marked in web/app.js:2.
- App SDK: custom graveyard app with live stats, real-time re-sync after every mutation, read-write everything β not a read-only frontend.
- Workflows: eulogy.state as data (submitted -> ghostwriter_review -> sanctified/rejected), agent reviews + human approves through the same transitions; decay cron moves status the same way. Verified: /api/health backend sanity 18/3, genuine tribute sanctified (Flash 22->27 soul, +1 flower), spam rejected with nothing written, bury/filter/exorcise/decay-tick (18 patched) all on Sanity, static 200, test docs deleted and dataset re-seeded canonical.
Sanity Project Details
- Project ID: s2icbb2m
- Dataset: production (public read, token write)
- Public queries:
- Corpses: https://s2icbb2m.api.sanity.io/v2024-01-01/data/query/production?query=*%5B_type%3D%3D%22deceasedProject%22%5D%7B_id%2Cname%2CvitalityScore%2CflowersLeft%2Cstatus%2CcauseOfDeath%7D
- Counts: https://s2icbb2m.api.sanity.io/v2024-01-01/data/query/production?query=%7B%22corpses%22%3A%20count(%5B_type%3D%3D%22deceasedProject%22%5D)%2C%20%22eulogies%22%3A%20count(%5B_type%3D%3D%22eulogy%22%5D)%7D
- Seed: scripts/seed-sanity.js β verified Seeded 18 deceasedProject + 3 eulogy docs
- GROQ (server.js): [_type=="deceasedProject"] | order(vitalityScore desc) *[_type=="eulogy" && project._ref==""] | order(createdAt desc) count([_type=="deceasedProject" && lower(name)==""])


Top comments (0)