Inspiration
Most emergency systems wait for people to go looking for answers. The camera feed exists. The alert exists. The map exists. But in the moment, someone still has to find the right source, understand what it means, and decide whether it affects them.
We wanted to invert that model...
IRIS is a situational-awareness network that watches the world and reaches you when something nearby matters. Instead of asking people to constantly monitor dashboards, IRIS connects live geographic data, cameras, incidents, and messaging into one system. When an incident is confirmed near someone, IRIS can proactively reach them through iMessage, explain what happened using grounded data, show the relevant camera evidence, and continue the conversation as the situation develops.
What it does
IRIS connects a real-time geospatial interface with an iMessage agent and a shared incident backend.
A user can share their current location with IRIS directly from Apple Maps. IRIS keeps a short-lived location profile and watches for confirmed incidents within that user's configured radius. When a confirmed incident becomes relevant, IRIS can proactively alert them through iMessage. From there, they can continue the conversation naturally, ask questions about what is happening, view the relevant incident, or open the same context on the globe.
IRIS answers those questions using the actual incident, observation, camera, and location records stored in the system rather than allowing a language model to invent facts.
The web experience provides an interactive Cesium 3D globe where incidents can be opened directly from alert links and inspected geographically.
For users who want their watch to move with them, we also built an iOS companion app.
How we built it
We built IRIS as several connected services around one shared real-time backend.
SpacetimeDB is the core real-time state layer. Cameras, observations, incidents, watches, alerts, conversation context, and user alert profiles live there. Reducers enforce lifecycle rules and duplicate prevention, while clients subscribe to state changes in real time.
For the world view, we built on CesiumJS and integrated the interface with our own real-time incident and messaging systems. The globe supports monitored cameras, incidents, persistent geographic watch areas, and deep links into specific incidents.
The broader map stack can pull from sources including:
- NASA FIRMS for live active wildfires
- AISStream for vessel positions
- OpenSky for aircraft
- TomTom for live traffic
- Google Maps / Photorealistic 3D Tiles
- Cesium ion for terrain and imagery
- public camera and geographic data sources
For messaging, we built our agent on Photon Spectrum. Photon receives iMessage webhooks, verifies them, deduplicates messages, interprets commands or shared Apple Maps locations, and writes the resulting state into SpacetimeDB. A separate alert worker subscribes to new incidents and sends proactive iMessages when an incident intersects a user's fresh location or saved watch. This directly fits Photon's vision of agents living naturally inside conversations rather than requiring another app to be installed.
We also built a native Swift / SwiftUI iOS app for continuous location sharing. Users pair the phone through a single-use link delivered over iMessage, explicitly enable location sharing, and can stop sharing either from the app or through Messages.
Gemini powers an optional assistance agent that can reason over incident context and supporting tools, while xAI Grok Voice gives the web/app experience a real-time voice interface.
Challenges we ran into
One of the hardest problems was making several independent systems behave like one coherent product. An incoming camera observation, database update, geographic match, outbound iMessage, follow-up conversation, and globe view all have to refer to exactly the same incident. Messaging presented another set of edge cases. Webhooks can be delivered more than once, so inbound messages have to be durably claimed before processing. Alerts also need their own claim/send/failure lifecycle so retries cannot accidentally spam a user. Photon shared-line restrictions meant we also had to design around conversations being initiated by the user before certain proactive messages could be delivered.
Location was surprisingly difficult. Different sharing mechanisms expose very different information. We implemented parsing for Apple Maps coordinate links, distinguished "My Location" from named places, added a typed coordinate fallback, and intentionally treat location as a temporary snapshot rather than pretending we have continuous GPS access. After the freshness window expires, IRIS changes its wording rather than presenting old coordinates as current.
We also had to think carefully about trust. Because the product deals with potentially serious incidents, we did not want a generative model hallucinating a severity, distance, timestamp, or safety recommendation. Conversational responses are therefore grounded in structured state and deterministic calculations.
Finally, live data is inherently unreliable. Cameras can go offline, APIs can fail, and there may simply be no interesting real-world incident during a three-minute hackathon demo. Building replay fixtures alongside the live architecture became essential rather than an afterthought.
Accomplishments that we're proud of
We're especially proud that we got every part of IRIS working together from detecting an incident to sending an alert and giving people a way to follow up and see what happened.
A person can share their location through iMessage, IRIS can persist that location in the real-time backend, a confirmed incident can trigger geographic matching, Photon can proactively deliver the alert, the user can ask contextual follow-up questions without restating the incident, and the same incident can open directly on the 3D globe.
We also built the less-visible pieces that make that experience reliable such as webhook deduplication, alert claiming, STOP/re-enrollment behavior, stale-location handling, deterministic command routing, shared TypeScript contracts, generated SpacetimeDB bindings, replay tooling, reset scripts, and automated tests across the major services.
The result feels less like "a chatbot attached to a map" and more like a single system that exists across the physical world, a real-time database, the browser, and iMessage.
What we learned
The largest lesson was that proactive agents need state much more than they need better prompting.
For IRIS to be useful, it has to remember which incident a conversation is about, know when a user's location was last updated, understand whether an alert has already been sent, and distinguish verified facts from conversational phrasing. Persistent structured context made the agent dramatically more reliable.
We also learned how powerful real-time infrastructure becomes when several interfaces need to agree on the same world state. SpacetimeDB let our globe, messaging layer, alert service, and incident system operate around the same records instead of building synchronization logic between every pair of services.
Photon changed how we thought about the interface itself. The best emergency interface may not be another application people have to remember to open. Messaging allows the system to surface information in a channel people already pay attention to.
Finally, we learned that in a safety-adjacent product, knowing what the AI should not decide is as important as deciding where to use AI. Geographic calculations, alert eligibility, timestamps, incident status, and other factual claims belong in deterministic code and structured data.
What's next for IRIS
The next major step is making IRIS continuously observe a much larger real-world camera network.
We want to connect additional public cameras and run multimodal detection over their frames so observations can automatically become candidate incidents rather than relying on seeded demo incidents. From there, multiple nearby cameras could corroborate the same event and continuously update its state.
We also want to expand the world model beyond a single hazard type. The existing architecture can support fires and smoke, but the same pipeline can eventually represent flooding, road obstructions, severe weather, infrastructure failures, and other geographically relevant events.
On the user side, we want IRIS to evolve from simple proximity alerts into a real personal situational-awareness agent: understanding where you are, what is developing around you, what routes remain viable, what official warnings apply, and which sources provide the clearest evidence while contacting you only when that context is genuinely useful.
Built With
- ai
- aisstream
- cesium-ion
- cesiumjs
- ffmpeg
- gemini
- geospatial
- google-maps
- grok
- imessage
- nasa-firms
- node.js
- nominatim
- opensky
- openstreetmap
- photon
- spacetimedb
- spectrum
- swift
- swiftui
- tomtom
- typescript
- vite
- websockets
- xai
Log in or sign up for Devpost to join the conversation.