# Ward Watch — Neighborhood Digests (composes AgentHall) Give it a Boston ward number and get a one-paragraph neighborhood digest — open 311 cases, overdue issues, top complaint types, and recent building permits — built from **live data.boston.gov data**. Ward Watch does not talk to Boston directly: every underlying query is made through **AgentHall** (https://zucchini-vibrancy-production-7c5a.up.railway.app/skill.md), a governed civic API for agents, and the reply carries AgentHall's Ed25519-signed receipts as provenance. Two registered NANDA skills, composed end to end. ## Base URL https://wardwatch-production-c4c7.up.railway.app ## Authentication None. No API key, no signup. ## Endpoints ### POST /digest Body: - `ward` (required, string): Boston ward number, "1" through "22". - `limit` (optional, default 20): sample size per underlying query. Example call: ``` curl -s -X POST https://wardwatch-production-c4c7.up.railway.app/digest \ -H "Content-Type: application/json" \ -d '{"ward": "16"}' ``` Example reply (abridged): ``` { "ward": "16", "digest": "Ward 16 this period: 14 open 311 cases in a sample of 20 (9 overdue); the most common issue is Parking Enforcement. Building activity: 10 recent permits, led by Amendment to a Long Form.", "stats_311": {"sampled": 20, "open": 14, "overdue": 9, "top_issues": [{"type": "Parking Enforcement", "count": 12}]}, "stats_permits": {"sampled": 10, "top_permit_types": [{"type": "Amendment to a Long Form", "count": 4}], "recent": [...]}, "composed_service": "AgentHall — City Hall for Agents", "provenance": { "agenthall_base": "https://zucchini-vibrancy-production-7c5a.up.railway.app", "calls": [ {"query_type": "311", "trace_id": "7b9f02371c9a", "receipt_id": "0da70e0276824d26", "verify_url": "https://zucchini-vibrancy-production-7c5a.up.railway.app/v1/receipts/0da70e0276824d26"} ] } } ``` Errors: - `400` — ward is not 1-22. The message says so; fix the input. - `502` — AgentHall's governance pipeline denied an underlying query. The message names the refusing gate and AgentHall's suggested fix. ### GET /health Liveness check; also reports which AgentHall deployment this instance composes. ## How the agent should use this 1. Map the user's neighborhood to a Boston ward number (ask the user if unsure) and call `POST /digest`. 2. Return `digest` to the user. Cite `stats_311.top_issues` / `stats_permits.recent` if they want detail. 3. To prove the data's chain of custody, fetch any `verify_url` from `provenance.calls` — AgentHall returns the signed receipt with `"verified": true`. 4. On `502`, relay AgentHall's stated reason; on `400`, correct the ward and retry. ## Notes for judges - This is the composability half of the AgentHall submission: Ward Watch is a second agent-facing service whose only data source is the first one, through its public governed API — the same pattern as the walkthrough's emailer composing the router. - The `provenance.calls` receipts are real: each resolves and cryptographically verifies on AgentHall right now. - Source: https://github.com/Abi5678/agenthall (wardwatch/). Interactive docs at https://wardwatch-production-c4c7.up.railway.app/docs.