What inspired us
Controllers at busy airports like Detroit Metro (DTW) constantly combine weather reports, nearby traffic, schedules and FAA restrictions in their heads. We wondered whether a small team of AI agents could watch that live data and surface short, evidence-backed suggestions, without ever taking the decision away from a human.
What it does
WatchTower is a prototype flow-advisory assistant for DTW:
- Live data in: aircraft positions (ADSB.lol), FAA airport status, and optionally FlightAware schedules are ingested into SpacetimeDB, where each case is frozen as an immutable evidence snapshot.
- Three Fetch.ai agents cooperate: a Weather agent, a Flight Congestion agent and a Validation/Coordinating agent exchange structured messages about the same snapshot.
- Projections, not predictions: the congestion agent runs a deterministic baseline-vs-proposal model of departure queues (e.g. "what if releases were capped at 30/hour for 15 minutes?"), showing runway and upstream waiting.
- Validation before anything is shown: the validator confirms the evidence exists, is live and fresh, recomputes the projection, and checks that every number matches, that the action is in a bounded catalog, and that weather and traffic agree. Only then does it publish an advisory for human review. It never approves anything itself.
- Ask it in plain English: controllers can chat with the validator on ASI:One ("what's pending and why?") and get answers grounded only in validated facts.
- Mission-control dashboard: live traffic, advisories, projections and validation reports in one view.
How we built it
- Agents: Python with Fetch.ai uAgents, run together in a Bureau. They use signed messages, sender allowlists, and a bounded protocol (one snapshot per case, at most one reassessment).
- Data and state: SpacetimeDB (TypeScript module) with role-checked reducers for ingestion, evidence snapshots, findings, candidates, projections and validation reports.
- Frontend: React + TypeScript with live SpacetimeDB subscriptions and a map view.
- Generative AI: the ASI:One API powers the validator's chat. Code builds a JSON of validated facts and the model only phrases the answer, with a templated fallback if the API is unavailable. All calculations, checks and approvals are deterministic code.
- How we split the work: we designed the technical implementation plan ourselves: the architecture, the three-agent protocol, data sources and safety rules. An AI coding assistant (Claude Code) wrote most of the code from that plan, and testing was shared. The AI wrote automated tests (450+ Python tests plus frontend and backend suites), and we ran, reviewed and tested the agents ourselves.
Challenges we ran into
- Honest data: "no aircraft in the feed" is not "no traffic," and a failed feed is unknown, not zero. We had to carry that distinction through every layer.
- Agreeing on numbers across services: the database re-derives projection demand to verify it, so our agent and the database had to bucket flights in exactly the same way.
- Inputs we couldn't observe: stored flight records had no gate times, so the starting departure backlog was unknown. We made it an explicit, clearly labeled operator setting, and built the path to use real gate times once they're stored.
- Parallel work: three agents, a database and a frontend built at the same time meant frequent merges and refactors that moved shared code around. Keeping tests green through each merge was its own project.
Accomplishments that we're proud of
- An end-to-end path from a stored live snapshot through congestion and projection to a validated advisory, with every number traceable to its evidence.
- A validator that catches tampered or inconsistent numbers and keeps every decision with a human controller.
- A chat interface that can't invent data, because the model only ever sees validated facts.
- A projection model that never hides delay: holding aircraft at the gate shows up as waiting, not as savings.
What we learned
- Keep generative AI at the edges: use it for language, not for numbers or decisions.
- Missing data is not zero: unknown inputs must stay visibly unknown.
- Projections must be honest.
(initial backlog plus demand equals aircraft served plus those still waiting upstream, queued or in transit).
- Strict contracts make teamwork possible: UTC times, explicit units and evidence IDs on every number let separately built agents trust each other's outputs.
What's next for WatchTower
- Store validated advisories in the database and connect approve/edit/ignore to authorized controller identities.
- Store gate times so the departure backlog is observed instead of configured.
Built With
- adsb.lol-api
- css
- fetch.ai-uagents
- html
- javascript
- maplibre-gl-js
- node.js
- openfreemap
- python
- python-unittest
- react
- react-testing-library
- spacetimedb
- typescript
- vite
- vitest
Log in or sign up for Devpost to join the conversation.