DEV Community

Cover image for Afterlight: tiny objects, improbable afterlives, and a human final say
prabhakar srivastava
prabhakar srivastava

Posted on

Afterlight: tiny objects, improbable afterlives, and a human final say

Sanity Challenge Path Two Submission

This is a submission for the Sanity Challenge, Path Two: Vibe-Code Something Strange.

What I Built

A museum from 2126. Everyday objects, imagined stories, and a curator’s final say.

What would a museum a hundred years from now make of a cassette, a house key, or a light bulb?

In Afterlight, a cassette can become a pocket-sized time machine. A key is permission to come home. A light bulb is borrowed sunrise. Visitors explore ordinary objects with improbable afterlives, while curators decide which stories belong in the exhibition.

The app opens directly into the collection. You can rotate eight original 3D reconstructions, filter collections, inspect objects, and export catalogue records. You can also upload an image of your own object and take it through a complete curator workflow:

Intake → Draft → Review → Exhibition → Withdrawal

The central rule is simple: AI can propose a story. A human decides whether to exhibit it.

Observed details and fictional interpretations have separate fields. Uploaded images remain images; the app does not pretend to reconstruct them in 3D. Gemini’s suggested catalogue details are labelled unverified, and they only enter the form when a curator explicitly selects Use these details.

Demo

Gemini suggests catalogue details, which stay separate from the form until the curator accepts them

The recording uses the deployed app with real Sanity and Gemini. The sample upload is a render of an original cup model. Authentication and provider waits were edited out; the narration uses a synthetic Microsoft Ava voice. The temporary exhibit was withdrawn and cleaned up after recording.

Try the curator workflow

Visitors can browse without signing in. To test editing, open Curator desk and enter this shared application curator code:

88100113c855c22b561f2af754a350f8c69f88b9dcabd61f
Enter fullscreen mode Exit fullscreen mode

This is the app’s curator access code, not a Sanity or AI-provider API key. It enables changes in the shared demonstration collection.

  1. Inspect the cassette. Rotate it and compare the observed details with its fictional interpretation.
  2. In Curator desk, choose New object → Your photo. Use an image you own or have permission to upload publicly.
  3. Give consent, request Gemini suggestions, review them, and select Use these details if appropriate.
  4. Save the intake record, draft a fictional interpretation with AI, edit the exhibition label, and submit it for review.
  5. Approve the exhibit. Open the public collection in another tab to see it appear, then inspect From object to exhibit for its recorded decisions.
  6. Return your test exhibit to draft with a reason when finished. It disappears from the public gallery while its workflow history remains.

Please create your own test object and leave the starter exhibits intact. Uploaded images can remain accessible by their CDN URLs after withdrawal, so use a non-sensitive image.

The curator reviews the exhibition label before approving the object

Code

Public GitHub repository: prabhakarcs786/afterlight

The repository includes setup instructions, Sanity schemas, workflow logic, tests, and the demo assets.

The stack is Next.js, TypeScript, Sanity Content Lake, Three.js, Gemini, and Vercel.

Sanity Project Details

  • Project ID: solj2ppn
  • Dataset: production — private
  • Public access: approved exhibits through the application
  • Curator access: the application code above

How Sanity shapes the experience

The schema models collections, artifacts, and embedded workflow events. Each artifact references a collection and separates observed material and details from fictional interpretation, exhibition copy, and a strangeness rating.

Photo exhibits use native Sanity image assets with alternative text. Images are validated, resized, and stripped of metadata before upload.

A workflow transition writes its new state and event together, guarded by Sanity’s revision precondition. If another curator changes the record, an outdated editor receives a conflict instead of silently overwriting it. The UI preserves the unsaved text so the curator can recover their work.

A server-side Sanity listener notifies browsers of changes. Each browser then refetches its public or protected view. This lets a visitor see an approval or withdrawal without manually reloading, while Sanity credentials stay on the server.

This is a custom application workflow built on Content Lake. I did not use the early-access Workflows engine or App SDK.

An exhibited object exposes its retained workflow decisions to visitors

Starter exhibits are explicitly identified as seed snapshots. The app does not manufacture approval events for them; newly processed objects show their actual retained events.

My Build Process

I used GitHub Copilot in VS Code for the initial build and Codex for release review, verification, and the narrated showcase. The concept, implementation, models, and tests were developed with AI assistance. These are retrospective build notes rather than a verbatim prompt transcript.

1. Start with the rules

Before polishing the screens, I established three constraints: automation cannot approve, incomplete labels cannot enter review, and an exhibited object must return to draft before editing.

Those rules became a shared transition function used by the local demo and the live persistence path. That made the behavior easier to check than rules scattered across buttons.

2. Give the museum real objects

Eight original models were assembled in Three.js. A rendering script generated their thumbnails, and the detail view kept them interactive. Browser checks verified that the scene contained visible pixels and changed when rotation was enabled.

One release issue was surprisingly mundane: development UI badges had been captured in thumbnail screenshots. Exporting the canvas directly fixed the images.

3. Make participation personal

Choosing from eight objects was a useful beginning, but contributing your own object made the idea more compelling. Photo intake added that possibility.

It also introduced another decision: should AI fill the form automatically? I chose reviewable suggestions with explicit acceptance. The curator can distinguish what they entered from what the model inferred before saving anything.

4. Let testing challenge the implementation

Type-checking caught overly broad Sanity create types and, later, a renderer that incorrectly accepted the new photo kind. The renderer now accepts only the eight actual model kinds.

Browser accessibility checks caught low-contrast workflow counters. Reusing the existing muted text color fixed the measured issue. The first Vercel deployment also used the wrong framework preset; explicitly configuring Next.js resolved it.

5. Verify the live loop before recording

Local checks were followed by real Sanity and Gemini exercises on the deployed application: image suggestions, asset storage, AI drafting, review, approval, withdrawal, and stale-write rejection.

Separate curator and visitor browser sessions confirmed that public exhibits appeared and disappeared through live updates. Temporary verification objects and their newly uploaded assets were removed afterward.

Verification

On 2 October 2026, the release passed:

  • 57 unit tests and 12 desktop/mobile browser tests.
  • Lint, TypeScript checking, production build, and Sanity schema extraction.
  • Automated accessibility checks and a dependency audit with zero reported vulnerabilities.
  • Hosted photo and curator workflows using real Sanity and Gemini.
  • GitHub CI, plus checks of the recording, captions, screenshots, and public media links.

The demo uses a shared curator code and retains the latest 100 workflow events per object. It does not provide individual curator identities or an immutable audit log. Those are clear next steps for a larger museum deployment.

What I Learned

The most useful part of this experiment was turning a strange premise into precise content rules.

Sanity’s schema helped define what had been observed, what had been invented, and what a human had approved. AI made the museum imaginative; those boundaries made it understandable.

Visit Afterlight · Watch the walkthrough · Explore the code

Top comments (0)