Inspiration
A missing-person poster is a public record, and then it goes quiet. The Washington State Patrol page lists adult cases with a name, a photograph, a last-seen date, and a PDF. If you want to follow one person, you keep the tab open and hope you remember to look again.
We built clonacase as a desk for that poster. Search a name, open the timeline, and clone the case into your own repository. The repository starts private. You can add a note, a source, a photo or article link, or a hypothetical event. A hypothetical line is a reading. It is not a finding. When the notes are ready, you can share the repository, and someone else can clone it or send a change back as a pull request.
Photographs and PDFs stay on the state site. The app does not scrape accounts, search the web for a suspect, or keep an offender list. A note that names a suspect, a private street address, or a family member who is not on the poster is held back before it can be sent.
People already live in their messages. Following a case on the site also subscribes an iMessage chat, through Photon 2.0, so a public change can arrive on the phone without another visit to the page.
What we learned
A public case file and a private working desk are different objects. The poster is the shared record. The repository is one person’s copy, with their notes, and it stays private until they share it. A clone is a new private desk tagged with who it came from. A fork is stricter: new notes do not land on the original until the owner accepts a pull request.
The draft taught us to keep the model on a short leash. A brief is composed from the milestones already in that repository. It retells the sourced sequence, lists leads, and leaves inconclusive notes out of that sequence. Between two sourced dates it records a gap when where is the number of days between those dates. The draft cannot browse, name a suspect, or predict a place. If there is no sourced milestone, the draft says so.
There's also contribution chart for user profile. It counts private clones and new information: notes, sources, hypothetical events, and pull requests you authored. A fork is not a clone. A note copied across from someone else’s repository does not count as new.
On the phone, we learned that a shared iMessage line cannot text first (at least for now). The person messages the assigned number once. After that, a subscribe sends “You subscribed to {name}” in that chat, and later public updates use the same conversation. Photon 2.0 is its own API. The older Spectrum project id and secret do not open it.
How we built it
clonacase.club is a Next.js app with TypeScript, Tailwind, and a small set of interface components. Adult posters are taken from the Washington State Patrol missing-persons list. Choosing a name opens that person’s timeline, photograph, and poster link.
Sign-in is an email and a password, or an anonymous username on a first visit. The username is the name on the desk. Emails and passwords are not written down. The session is a signed cookie.
The case page is the public file: poster facts, a discussion, and the public repositories other people have shared. Your own repository holds the working notes, media, and hypothetical timeline. Sharing it asks you to confirm that the notes name no suspect, and every sourced note needs a source name. From someone else’s public repository you can clone a private copy or fork it. Forked work waits on the pull-request page. The same hold-back runs there, with Gemini when a key is set and with the same local checks when it is not.
The store is MongoDB when a connection string is present. Poster dates, repositories, discussion, and pull requests each have a place. If that database refuses the connection, the same desk is kept in a private blob file so a clone still saves.
Photon is the message layer. Follow a case or a repository on the site, or text a poster name to the line. A public change on a followed case, a note, comment, source, hypothetical event, working note, or a repository just made public, is sent in the iMessage chat. The agent also answers there. A name follows a poster. list shows what you follow. stop ends one. latest reads the newest public update. A question is answered from the poster and the public notes. Photon posts each new text to the app as it arrives, and a once-a-minute check is the backup.
Challenges
The hard part was scope. A missing-person desk can slide into accusation, doxxing, or a guessed location. We kept the public actions small: quote the poster, attach a source, mark a note as sourced, a lead, or inconclusive, and say when the sourced record has a gap. The pull-request check and the outgoing texts use the same rule. If a line matches a suspect, a street address, or a family role that is not on the poster, it is held back.
Counting work on the profile was easy to get wrong. An original desk still counts if it is later made public. A clone counts. A fork does not. Seeded poster dates are not new information. A file copied in with an older timestamp is not a new source. The chart only lights up for work that person actually added.
We have some struggles still try to set up Photon to work smoothly for being an agent that alerts to users, and still need to get it updated in real-time whenever the case changes.
Demo
The demo runs on real Washington State records. Search uses adult public posters from the Washington State Patrol missing-persons list. Pick a name and the timeline, photograph, and poster open from that record. The photograph and the PDF stay on wsp.wa.gov. Anyone under 18 is left out.
Open clonacase.club, choose an anonymous username, and clone one of those cases into a private repository. Add a note or a source. Share it only after confirming the notes name no suspect. Follow the case and the iMessage line texts you when a public repository of that case changes. The answer comes from the Washington State record and from the public notes already saved on the desk.
Built With
- cursor
- gemini
- github
- html
- javascript
- mongodb
- next.js
- node.js
- photon
- react
- tailwind
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.