Inspiration

A boil-water advisory reaches a dialysis clinic, a school and a long-term-care home in the same second. The message is identical. The work is not.

Dialysis has to verify treatment water and a continuity plan. The school has to secure drinking and hygiene water and hold food service. The care home has to protect resident care and environmental services.

Today's tools define the zone, send the alert, log the approval, and stop. An alert gets treated as a response. Nobody checks the last institutional mile, and nobody notices the facility that simply never replied.

The research says this gap is where people get hurt:

One Advisory starts exactly where those tools stop. An alert should not be the last thing that happens.

What it does

One Advisory takes an already-authorized advisory and carries it through to a verified, closed response, and it keeps working while nobody is watching.

1. It writes the plan, it does not just forward it. Model Armor screens the advisory text before any model reads it. Gemini keeps only facts it can quote word for word, then writes a different playbook for each facility from this advisory's actual wording and that facility's capacity. Every task must cite a registered public-health source, so anything the model invented is dropped before a human sees it.

2. Five agents decide who acts next, under a ceiling they cannot raise. A planner agent chooses which specialist runs next and why, including choosing to wait while facility replies are still plausible, which a fixed script can never do. Four specialists then each authorize their own action. Anything outside the registered set of allowed actions is refused by name, and the compliance check cannot be skipped. Each of the five runs on its own managed runtime with its own identity, behind one governed gateway.

3. It acts on wall-clock time, not on clicks. Work that happens later is written to Firestore as a durable wake. Cloud Scheduler wakes the service every minute with a signed Google identity. When a facility goes silent past its deadline, the wake escalates it to the duty officer, schedules a recheck, and resumes the fleet on its own. Nobody is at the keyboard. The autonomy receipt reports operator_continue_clicks: 0.

4. Facilities can answer the way they actually would. Through the console, a keyed API, or a Pub/Sub feed. They can phone it in. A spoken report is transcribed and mapped to a registered event kind, and a call it cannot confidently classify goes to a human with the transcript rather than being guessed into an acknowledgement. They can send a photo. Gemini judges whether the image supports the claim, and one that does not is downgraded and flagged, never recorded as evidence.

5. It stops where human authority begins, and proves it. When two facilities need the same delivery slot, the fleet lays out the options and picks nobody; a named commander decides. It cannot issue an advisory, rescind one, close a facility, or allocate a resource. After the advisory lifts it verifies recovery per facility, drafts the after-action briefing from the audit trail, and schedules a 42-day follow-up so a closed incident wakes up weeks later.

How we built it

One FastAPI service on Cloud Run. Every way an event can arrive (console, API, Pub/Sub, a durable wake) funnels through the same module, so the same screening, evidence rules and authority gates apply no matter the channel.

Piece What it does
Gemini 3.5 Flash reads the advisory, writes per-facility playbooks, verifies photos, drafts the after-action
Gemma 4 triages facility replies and flags ones that contradict the declared event
Vertex AI Agent Engine 5 ADK agents, each with its own Agent Identity, catalogued in Agent Registry
Model Armor screens model inputs and outputs inline
Firestore incidents with optimistic versioning; durable wakes claimed inside transactions
Cloud Scheduler wakes the service every minute over OIDC
Pub/Sub facility events via an OIDC-verified push subscription
Cloud Trace, Secret Manager request correlation; HMAC pepper and API keys

Reproducible: deploy.sh and the infra/ provisioning scripts stand the whole thing up, and scripts/demo_flow.py runs 33 executable checks against any deployment, so a judge can verify a live system instead of taking our word for it. The proof endpoints (/api/proof, /api/planner/proof, /api/platform) read from Google's APIs and fail closed rather than reporting healthy when they cannot confirm it.

Challenges we ran into

Making a planner useful without letting it invent authority. A model that picks the next step will eventually pick a step that does not exist. So the plan is advisory only: the registry refuses unknown roles and human-reserved decisions by name, repeated steps are treated as a loop, every step is rechecked against live state as it executes, and a planner outage falls back to the registered sequence.

Deciding what an agent may never do. The hardest design work was not capability, it was restraint. Resource allocation looks automatable and is exactly the thing a human must own, so "propose the options, pick nobody" became a first-class outcome rather than a failure.

Telling a refusal apart from an outage. A managed runtime saying no and a managed runtime being down look almost identical at the call site and mean opposite things. They now split cleanly: a refusal is a 409 and is final, an outage is a 503 that retries, rebuilds its handle, then fails closed.

Trusting time when nothing is watching. Wakes have to survive restarts and fire exactly once across many instances, so they live in Firestore and are claimed inside transactions with leases and a dead-letter path.

Accomplishments that we're proud of

  • It runs with zero human continue clicks, and the system proves that from its own persisted trace rather than asserting it.
  • A silent facility has consequences. The escalation fires on wall-clock time with nobody watching. That single behaviour is what separates this from a notification tool.
  • The refusals are real. A hallucinated action is refused by name, the compliance step cannot be skipped, and the resource decision stays human.
  • It adapts per facility. Adding another facility type means registering another playbook, not rebuilding the system.
  • The proof is live, not screenshotted. The platform endpoint reads Google's APIs and fails rather than pretending.

What we learned

Autonomy is a governance problem far more than a model problem. The interesting question was never "can the agent do this," it was "what must it never do, and how do we make that structural instead of a polite instruction in a prompt."

Grounding beats fluency. Forcing every task to cite a registered source made the output less impressive-sounding and far more trustworthy, and it is what lets invented work be dropped automatically instead of reviewed by a human later.

And durable state changes what an agent is. Once work survives in Firestore and a scheduler can wake it, the agent stops being a request handler and becomes something that keeps a commitment over weeks.

What's next for One Advisory

  • More facility classes: hospitals, correctional facilities, water-dependent manufacturing, each a registered playbook rather than a rewrite.
  • Real advisory feeds instead of a synthetic one, keeping issuance and rescission strictly external.
  • A real acknowledgement channel (SMS and voice callback) so facilities reply the way they already do.
  • Cross-incident memory, so a facility that struggled last time gets a longer lead and closer follow-up.
  • Beyond water. Boil-water is the clearest case, but power loss, air quality and supply interruption have the same shape: one alert, many realities, no verification.

Everything shown is synthetic. One Advisory records an already-authorized exercise advisory; it does not issue public-health instructions, and we claim no health outcome.

Built With

  • adk
  • agent-engine
  • cloud-run
  • cloud-scheduler
  • cloud-trace
  • fastapi
  • firestore
  • gemini
  • gemma
  • google-cloud
  • model-armor
  • pub-sub
  • python
  • secret-manager
  • vertex-ai
Share this project:

Updates

Submission history