Inspiration

Small urban streams are everywhere and almost no one checks them, yet people and dogs touch the water every day. Citizen science can fill the gap, but collecting reports is the easy half. A report on its own is hard to believe and hard to compare, so what a city needs first is an answer to "how far do I trust this?". Rivulet is built around that question: it weighs reports, says how sure it is, and says "insufficient data" when it does not know.

Track alignment statement

Primary: Track 2, Data-to-Insight. Rivulet turns citizen stream observations into interpretable, decision-ready insight: an uncertainty-aware status for each stream, a One Health reading of who and what is exposed, a city report that says where to take care and where a visit would help most, and trends over time.

Also addresses Track 5 (Community & Gamification): a private journal with badges, a leaderboard whose points reward validated, trust-weighted reports and filling data gaps, and signed volunteer certificates. And Track 7 (Digital Health Standards): a read-only FHIR R4 endpoint profiled to the OneAquaHealth Implementation Guide and validated with the HL7 validator in CI. It touches Track 3 in a deliberately limited way: an optional AI check flags a photo for a person, and a person decides.

What it does

A resident photographs the water and answers a few plain questions in about two minutes, with no account. The colour is read on the phone on the Forel-Ule scale, and the full photo stays on the device. Rivulet then:

  • checks every report (GPS accuracy, distance from the stream, rate limits, an optional AI "is this water?" check) and holds doubtful ones for a person to review;
  • weighs each observer by how often they agree with others who reported the same stream;
  • turns the weighted evidence into a status class named after the EU Water Framework Directive, with a 90% credible interval, or says "insufficient data";
  • reads warning signs against the places people and dogs actually use nearby (playgrounds, schools, parks, dog areas), a One Health reading;
  • adds a coarse Sentinel-2 satellite cross-check;
  • gives a city report: where to take care, and where a visit would help most;
  • exports everything as FHIR R4 profiled to the OneAquaHealth guide, and gives volunteers a signed, verifiable certificate.

It installs as an offline-capable app: a report written without signal waits on the phone and is sent, with its true time, when the connection returns.

How we built it

Next.js 16 (App Router, TypeScript strict), React 19, Tailwind CSS 4, MapLibre GL, Supabase (Postgres, PostGIS, row-level security with column grants), Zod, pdf-lib, Ed25519 signatures for Open Badges 3.0 certificates, an optional Groq vision model for the photo check, GitHub Actions and Vercel. The science engine and the FHIR mapping are pure functions with 212 unit tests. On every change, a workflow builds the OneAquaHealth guide from source and runs the official HL7 validator on Rivulet's own output: 0 errors. Every constant in the model is either a cited standard or a declared, uncalibrated prior, published live on the /method page.

Challenges we ran into

  • Honest science with little data. We refused to invent calibration, so each constant is labelled and the model says "insufficient data" instead of guessing.
  • Thin streams, coarse pixels. Most urban streams are narrower than a 10 m Sentinel-2 pixel, so the satellite check stays grey for most of them, and we say so.
  • A standard that is still moving. The guide is a draft with no published package. We build it from source, and the validator found real defects in our first export, which we fixed.
  • Speed. The first map took seconds per city switch. It now renders at once, caches city data at the edge and swaps only the line data on the map.

Accomplishments that we're proud of

  • A deployed prototype covering the whole path: report, review, trust, estimate, One Health, map, city report, certificate, FHIR.
  • A read-only FHIR endpoint validated in CI against the OneAquaHealth guide.
  • A model that shows its uncertainty and its method instead of hiding them.
  • A signed, verifiable volunteer certificate with a QR code and a PDF.

What we learned

The hard problem in citizen science is not collecting but qualifying: who to believe, and how to say "we do not know yet" in a way people can act on.

Honest limits

  • Rivulet is indicative, not a laboratory, regulatory or public-health assessment; nothing here says water is safe.
  • Class limits are priors, not calibrated ecological quality boundaries; colour from a phone is an uncalibrated proxy.
  • Trust is peer agreement, not truth. The model is not yet validated against independent measurements.
  • Coimbra's observations are synthetic demonstration data, tagged HTEST in FHIR. The real reports are 12, all from one observer (Tashkent 6, Coimbra 4, Benevento 2). We claim no traction.
  • Not endorsed by the EU, IEEE or the OneAquaHealth consortium.

What's next for Rivulet

A pilot that tests the model: choose a city and streams with a partner, recruit volunteers, and compare Rivulet's estimates and trust with independent measurements from the OneAquaHealth field protocols. Then calibrate or retire the priors and measure usefulness to city services. Success would be repeat participation, the share of streams with a fresh report, the share of raised warnings that independent checks confirm, and the time and cost of a useful check.

Try it in three minutes

Open the live map, choose Tashkent or Coimbra and switch between the three layers. Open the City report, then a stream page. Open Open data to follow the live FHIR examples, and Method to see every constant.

Built With

Share this project:

Updates

Submission history