ποΈ CivicRelay: A Human-Gated Multi-Agent Pipeline for Autonomous Civic Issue Resolution and Predictive Infrastructure Monitoring
π 1. Project Overview
CivicRelay is an autonomous civic-issue resolution platform that we built to change how citizens report problems like potholes, broken streetlights, water leaks, and illegal dumping to their local government. The core idea is that reporting an issue shouldn't be the end of a citizen's involvement and the start of silence from the city, it should trigger an active, trackable, accountable process.
When a citizen (or a city sensor) reports a problem, CivicRelay's five-agent pipeline:
- π·οΈ Classifies it
- ποΈ Identifies the exact municipal department responsible and its statutory response window
- π Drafts a formal complaint and files it
- β±οΈ Actively monitors the deadline
- π¨ Escalates automatically to department leadership if the city misses its own SLA β but never without the citizen's explicit approval first
β 2. Problem We Wanted to Solve
Most city reporting systems - 311 hotlines, web forms, generic ticketing portals β are passive repositories. A citizen submits a report, and it disappears into a queue with no visibility into what happens next.
- π« No clear ownership β who is actually responsible for fixing this?
- β³ No deadline β is there a legal or policy timeframe the city is supposed to meet?
- π³οΈ No accountability β what happens if the deadline passes with nothing done?
- π No aggregation β ten people reporting the same pothole look like ten unrelated tickets
- π No proactive detection β infrastructure failures are only caught after someone notices and reports them, often after they've become dangerous
The problem isn't just "how do we let citizens report issues?" It's "how do we make sure a report actually leads to resolution and hold the process accountable when it doesn't?"
π‘ 3. Why We Chose This Project
We wanted to build something with real agentic structure - not a chatbot wrapper around an LLM, but a system where multiple specialized agents each own a distinct part of a genuine operational workflow:
- π·οΈ Classification
- ποΈ Department/jurisdiction lookup
- π Formal drafting
- π Ongoing monitoring
- π¨ Escalation
This also let us combine several areas we cared about in one system:
- π€ Multi-agent orchestration
- π Real external integrations (a municipal API standard, a messaging platform, and IoT telemetry)
- π§ββοΈ Human-in-the-loop safety design
- π Genuine predictive analytics
We didn't want to build a demo that only worked in the happy path - we wanted the system to behave correctly even when its AI dependencies were unavailable.
π₯ 4. Who Could Use This System
- ποΈ City governments and municipal departments looking to modernize 311-style reporting
- π Citizens who want visibility into whether their report is actually being acted on
- π§ Public works and utility departments managing physical infrastructure (roads, water, electrical, and waste)
- π‘ Smart-city programs with existing or planned IoT sensor deployments who want automatic fault detection layered on top of citizen reporting
- π Civic-tech and GovTech teams looking for an open architecture pattern for agentic public-service tools
Our current implementation is a hackathon-stage prototype demonstrating this architecture end-to-end; it is not yet a certified, production-hardened municipal system, and we're upfront about that distinction throughout this write-up.
βοΈ 5. How the System Works
The central architectural decision was to give every intake channel - the web app, WhatsApp, and IoT sensors - a single shared entry point into the same agent pipeline, rather than building separate logic per channel.
Web App / WhatsApp / IoT Sensors
β
Shared Orchestrator
β
Triage β Research β Action
β
Tracking Agent
β
Deadline Breached?
No β Continue Tracking
Yes β Escalation Agent
β
Citizen/Owner Approval
β
Escalated
No matter which channel a report comes through, it receives identical treatment - a WhatsApp message and a web form submission run through the exact same classification, routing, and drafting logic.
β¨ 6. Main Features We Implemented
- π€ Five-agent pipeline (Triage, Research, Action, Tracking, Escalation) on Strands Agents SDK + Amazon Bedrock
- π‘οΈ Deterministic fallback logic for every agent - the pipeline degrades gracefully rather than breaking
- π² Three intake channels: web/app, WhatsApp (real Meta Cloud API), and IoT sensor telemetry
- πΊοΈ Persisted, incrementally updated geographic clustering of related reports
- ποΈ Real Open311/GeoReport v2 municipal API submission, with a local reference fallback
- β° Background SLA-breach detection sweeping every open ticket on a fixed interval
- π§ββοΈ Human-in-the-loop escalation, drafted automatically, never sent without explicit approval
- π‘ IoT threshold evaluation with duplicate-report suppression for an already-flagged sensor
- π A genuine predictive-maintenance layer: linear regression forecasts sensor failures before they cross the threshold, plus recurrence detection for issues that come back after being marked resolved
- π Role-gated municipal analytics dashboard (citizen vs. staff)
- π JWT authentication, bcrypt password hashing, and rate limiting
- π Full audit trail β every agent action is logged per issue
- β 116+ automated backend tests, plus hands-on manual end-to-end verification of nearly every endpoint
π€ 7. The Five-Agent Pipeline
Each agent has one job:
- π·οΈ Triage Agent β classifies the report into a category (road infrastructure, waste management, water authority, or electrical infrastructure) and assigns a severity level, using Strands' structured output on Bedrock
- π Research Agent β resolves which municipal department owns that category and what its SLA response window is, via a real tool-call function rather than a hardcoded lookup
- π Action Agent β drafts a formal complaint and either submits it to a real configured Open311 endpoint or generates a local ticket reference
- β±οΈ Tracking Agent β runs on a background scheduler, sweeping every open ticket and comparing elapsed time against its SLA deadline
- π¨ Escalation Agent β drafts an escalation notice the moment a deadline is breached, but the ticket sits in an
awaiting_approvalstate until the ticket's owner explicitly approves it
We deliberately designed every agent with a deterministic fallback path. If Bedrock isn't configured or a call fails, a keyword classifier, a template complaint generator, or a locally generated reference number takes over instead. We tested this explicitly, forcing AWS calls to fail and confirming the system never hard-crashes; it just falls back to rule-based behavior and logs which path it took.
π² 8. Multi-Channel Intake: Web, WhatsApp, and IoT
π¬ WhatsApp reporting uses Meta's real WhatsApp Cloud API.
- π Incoming webhook requests are verified with HMAC-SHA256 signature checking before any payload is parsed
- β The verification handshake follows Meta's actual spec
- π§ͺ Tested against Meta's live sandbox, not just unit tests against a mocked payload
- π‘ Confirmed a genuine end-to-end round trip: a real signed webhook request reaching our server, being parsed, and flowing through the same orchestrator as a web report
π‘ IoT sensor ingestion accepts telemetry from sensors (or, since no real civic-infrastructure sensor hardware exists for a project at this stage, a simulator standing in for it) via an authenticated endpoint.
- π Each reading is evaluated against a per-sensor-type threshold
- π If a sensor is already reporting an active, unresolved issue, a repeated breach is logged against the existing case instead of spamming a duplicate β we specifically tested this deduplication behavior
πΊοΈ 9. Geographic Clustering
Reports of the same category within a fixed radius of each other are grouped into a persisted cluster rather than treated as unrelated tickets.
- π Clustering is incremental; a new report checks against existing clusters and either joins one or seeds a new one, rather than being recomputed from scratch on every request
- π₯ This is what powers the public community map: citizens can see "3 people reported a pothole here" without any individual identity being exposed
β±οΈ 10. SLA Tracking and the Human-in-the-Loop Escalation Gate
A background job sweeps every open ticket at a fixed interval, comparing the current time against each ticket's computed SLA deadline. The moment a ticket breaches its deadline, the Escalation Agent drafts an escalation message - but this is where we made a deliberate safety decision: the draft is held, never sent, until a human explicitly approves it.
- β
Enforced in code as an actual status gate (
awaiting_approvalβescalated), not left as a suggestion the model could ignore - π±οΈ The ticket's owner has to hit approve before an escalation notice is considered sent
We consider this one of the most important design decisions in the project - an autonomous system that can independently decide to escalate something to a department director without a human checkpoint is not something we were comfortable building, even for a hackathon demo.
π 11. Predictive Maintenance β Honestly Framed
We built a predictive layer using two genuinely computed, inspectable methods, not a trained model, and we're explicit about that distinction rather than letting "predictive" imply more sophistication than exists:
- π Trend forecasting β ordinary least-squares linear regression over a sensor's stored reading history, projecting when it will cross its failure threshold before it actually does
- π Recurrence detection β flags locations where an issue was marked resolved and then recurred afterward, a real signal that the underlying infrastructure, not just the symptom, needs attention
We tested this with a real scenario: feeding a genuinely degrading sensor reading through the actual ingestion endpoint (never crossing its threshold, so zero active issues existed), then confirming the prediction endpoint correctly forecast a breach days before it would have otherwise been detected.
π 12. Municipal Analytics Dashboard
A staff-only analytics layer exposes:
- ποΈ City-wide totals
- β SLA compliance rate
- π·οΈ Category/severity/source breakdowns
- π Daily trend data
- ποΈ Per-department load
- πΊοΈ A full, unfiltered geographic map
Everything needed for a department to see where they're falling behind. Access is enforced server-side via role checking; a citizen account hitting any analytics endpoint receives a flat 403, not a filtered or reduced view.
π 13. Security, Auth, and Data Integrity
- π Passwords are hashed with bcrypt β never stored in reversible form
- π« JWT-based authentication: the token carries only a user identifier, with the role looked up fresh from the database on every request
- π¦ Rate limiting on public-facing report and auth endpoints
- π WhatsApp webhook payloads verified with HMAC signature checking before being parsed at all
- βοΈ Escalation approval is ownership-based β a ticket owner approves their own escalation; this is distinct from and independent of the staff-role gate on analytics
- π Every agent decision β classification, clustering, authority lookup, complaint draft, escalation, and resolution β writes a free-text audit entry, so a ticket's full decision history can be reconstructed after the fact, including whether a step ran on a real model call or a deterministic fallback
β 14. Testing and Validation
We didn't want to rely on a demo script that only exercises the happy path. The project has:
- π§ͺ 116+ automated backend tests covering authentication, the full agent pipeline, clustering, ticket lifecycle, WhatsApp webhook handling, IoT ingestion and deduplication, predictive maintenance math, and analytics role-gating
- π Manual end-to-end verification of nearly every endpoint by hand, including a live WhatsApp message sent from a real phone, received through the real webhook, and processed through the real pipeline - confirmed independently through our own server logs, Meta's own dashboard status, and the ngrok request log
- π A full migration chain (multiple Alembic revisions) tested clean from a fresh database on every feature addition
π§ 15. Main Challenges We Faced
π¦ Getting the human-in-the-loop gate genuinely enforced, not just described in documentation, took real care; it would have been easy to let the Escalation Agent draft and send in one motion, and we deliberately split that into two steps with a status field standing between them.
π¬ Configuring a real Meta WhatsApp Business integration surfaced friction that never shows up until you try to wire it up for real:
- Webhook verification and field subscription are two separate steps that are easy to complete, but only one of the temporary access tokens expires in 24 hours
- Meta explicitly blocks real ("production") message delivery to an unpublished app's webhook - something we only discovered by reading Meta's own warning text on the dashboard, which then required using Meta's built-in webhook test-payload feature to get a genuine round-trip proof before publishing
π We also caught a real configuration bug during testing: our .env file was never actually being loaded by the application at all - environment variables only worked when exported manually in the same terminal session. That's now fixed with an explicit load_dotenv() call.
π 16. What We Learned
- π‘οΈ Building a pipeline that degrades gracefully turned out to matter more than we initially expected; a system meant to be reliable civic infrastructure has to keep working when its AI dependencies aren't available, not just when everything is configured perfectly
- π We also learned that real third-party integrations carry friction that's invisible until you actually build against them - Meta's publish-gate on webhook delivery, AWS Bedrock's separate model-access approval step, and Open311's varying implementation quirks across cities all needed hands-on debugging rather than reading documentation alone
π§ 17. Current Limitations and Future Improvements
CivicRelay is a working, tested prototype β not yet a production-hardened municipal deployment. Honest next steps:
- βοΈ Full live verification of AWS Bedrock inference across all five agents with production credentials
- π± WhatsApp media support β voice notes and photos sent via WhatsApp, not just text
- ποΈ A real pilot integration with a live city's Open311 endpoint
- π Production secrets management beyond
.envfiles - βΏ Formal accessibility review of the citizen-facing frontend
- π Multi-language support for the classification and complaint-drafting agents
- π Deeper predictive maintenance models as more real sensor history accumulates
β οΈ These are genuine next steps, not features we're claiming already exist.
π― 18. Overall Project Summary
CivicRelay started from a simple frustration - civic reports disappearing into silence - and grew into a full agentic pipeline connecting citizen reporting, municipal accountability, IoT-based proactive detection, and genuine predictive analytics, with a human approval gate built into the one place where autonomy mattered most: escalating a case to city leadership.
Report (Web / WhatsApp / Sensor) β Triage β Research β Action β Ticket Filed β Background SLA Sweep β Breach Detected β Escalation Drafted β Human Approves β Escalated β Resolved β Feeds Analytics & Prediction
β Every core claim in this project is backed by an actual test or a hands-on manual verification, not just a demo script.
Built With
- alembic
- amazon-bedrock
- amazon-transcribe
- amazon-web-services
- anthropic-claude
- apscheduler
- aws-bedrock
- bcrypt
- docker
- docker-compose
- fastapi
- jwt
- meta-cloud-api
- multi-agent-systems
- open311
- postgresql
- pytest
- python
- react
- sqlalchemy
- strands-agents-sdk
- typescript
- webhooks
- whatsapp-business-api

Log in or sign up for Devpost to join the conversation.