Inspiration

When cell towers die — storms, blackouts, disasters, remote trails — people still need to send a short voice note, a photo of a road, or an “I’m okay.” Radio meshes can carry tiny packets, but most chat apps assume broadband and treat “send” as “delivered.” We wanted messaging that gets the meaning through first, and never claims delivery unless the other person actually got it.

What it does

CHRP is a browser demo of an off-grid messenger on a LoRa-style mesh.

  • Send text, voice notes, and photos across several hops, even with packet loss
  • Voice is tiny (about 150 bytes a second); a written transcript arrives before the audio
  • Photos arrive in layers: a one-line caption, a small blur, then the sharper image
  • Delivered only after the receiver acknowledges it. Otherwise the badge says Unconfirmed, and anything that already arrived (caption, blur) stays on screen
  • A live mesh map and a phone UI per node, plus a panel that shows how many bytes each message really cost

How we built it

A Chrome app (React, TypeScript, Vite) that simulates the radio mesh in the browser: airtime, range, collisions, and multi-hop relay. Messages are split into small packets and repaired with erasure coding so a lost packet does not throw the whole message away. Voice uses Codec 2; photos use progressive WebP.

AI is only a side channel. A vision model writes the photo caption, and Whisper writes the voice transcript, both sent ahead of the media. Those calls go through a small server proxy so the API key never reaches the browser.

PRISM. Every caption and transcript call is traced to PRISM: which model ran, how long it took, whether it succeeded, and which route it was (/api/ai/caption or /api/ai/transcribe). The trace describes the call; it does not upload the photo or the audio. If PRISM is down, the message still sends — tracing never blocks the radio path. That gives us a dashboard for when the “meaning first” layer is slow, failing, or skipped.

Challenges we ran into

  • Radios collide if you transmit too fast. We had to pace packets or almost nothing survived, even with no extra loss.
  • “Delivered” is easy to fake. We capped repair attempts and show Unconfirmed when there is no acknowledgement, instead of a false checkmark.
  • Fitting a photo and a voice note into tiny packets meant aggressive compression, and stripping extra bytes the image encoder adds.
  • Real radio time is slow. The demo runs faster than the air so a judge can watch a message finish.
  • Caption and transcript must never hold up the message. They time out, and the app still works without AI keys.

Accomplishments that we're proud of

  • Messages still complete under heavy loss across several hops, and a failure shows up as unconfirmed, not as a fake delivery
  • The words and the blur show up before the full voice note or the sharp photo
  • A short judge demo: text, voice, photo, then we kill the middle of the mesh and the app stays honest
  • The byte panel matches what we measured, so the pitch is not hand-wavy

What we learned

  • On a bad radio link, sending the useful part first beats waiting for one perfect file
  • The delivery badge is the product. It has to match what actually happened
  • A simulator has to include airtime and collisions, not just a diagram of nodes
  • Measure the runs. Wide variation is real, and the story should say so

What's next for CHRP-AHMAD

  • Run the same messenger on real LoRa / Meshtastic hardware, not only in the browser
  • Clearer offline use for disasters and trails, including a simple retry when the path comes back
  • Optional on-device transcript and caption when there is no AI key
  • Group chats, and holding a message until the mesh heals

Built With

Share this project:

Updates

Submission history