Changelog
What changed, when.
since 2026-10-17
Live, with the work since 1.1.0
AquaLens runs in public; results show where the algae is and warn about patches; utilities can put their own lab samples beside the satellite; you can watch a lake with a line of your own.
Not yet a release: the science version is still 1.1.0, and none of this moves a public score. Production runs on Render and Vercel, deployed by a job that waits for the exact commit and checks it.
Product
- Where the algae is: a per-pixel chlorophyll map on the picture and the share of the water at the WHO alert levels; a Low result warns about patches when 10 % or more of the water reaches alert level 1.
- Your own lab samples beside the satellite, with how often the two agree on the WHO band.
- A line of your own for alerts, and the lakes you watch in Settings and from every email.
- What the next sample is likely to be, with how often that guess was right on lab data; AquaLens fits no forecast model.
- A trust strip on every result; no duplicate assessment without a newer satellite image.
Operations
- Production on Render (API and Postgres) and Vercel (web app), deployed by a manual job that waits for the exact commit and runs the production checks.
- A public page shows how the service is looked after, stage by stage, from CI records.
- Fixes from live testing: the right web origin, rate limits per real client, no rounding across a WHO line, and no "0 g" for a pipeline that measured nothing.
2026-10-17
Science that matches the lab
Results agree better with lab tests, cloud is never read as water, every result shows its satellite photo, what it means for swimming, pets, fishing and drinking water, and how sure it is.
Science version 1.1.0: six evidence-led fixes, each checked against reference scenes and signed off, and public scores restated where they moved. The score now measures water quality on the WHO chlorophyll alert levels; how well the water was seen is reported beside it as confidence.
Science (public scores move)
- The 2022 Sentinel-2 reflectance offset is removed: every band had read about 0.1 too bright, so clear water looked murky.
- Cloud, cloud shadow and thin cirrus are removed from every band. An assessment takes the newest scene with a clear view of the water, and a fully clouded lake is never scored.
- The 20 m bands are paired with the 10 m bands by geolocation, not array position.
- NDWI is McFeeters' green / near-infrared water index; the water test (NDWI > 0 and MNDWI > 0) now keeps 76–100 % of the water ESA classifies on the reference scenes, against as little as 4.7 % before.
- The score is chlorophyll-a on the WHO (2021) alert levels (12 µg/L starts medium, 24 µg/L high); turbidity and floating plants can raise it, never lower it. On 213 NOAA lab samples from western Lake Erie, the level matches the lab's WHO band 58 % of the time (33 % before) and flags all 3 samples above the EPA microcystin limit.
- Indices are medians over water pixels that do not touch land. Every assessment carries a confidence, a 90 % range and an experimental chlorophyll-a estimate; fewer than 50 clear water pixels is not enough to score.
Product
- Tap a lake and AquaLens traces its shoreline from JRC Global Surface Water.
- 12 months from space on each water body: one clear look a month, scored with the same science, with persistence and a seasonal trend.
- Per-activity verdicts (swimming, pets, fishing, drinking); the calmest reads "No warning signs".
- Watch a lake for a browser alert when its level changes; rainfall and water temperature around every image.
- Assessments as a STAC catalogue and CSV; past scores are restated in public when the science changes.
Trust and operations
- Editing and deleting need the operator key when one is set; assessments are rate-limited.
- 35 known vulnerabilities in production dependencies fixed; a dependency audit, SAST and secret detection run in CI.
- Every science change goes through Earth Truth reference scenes, a governed re-baseline and a science owner's sign-off.
2026-05-16
Initial release
The first version: pick a lake on a map and get a risk level from a satellite photo, with a written explanation and a PDF report.
Production-grade rewrite. Real Sentinel-2 retrieval via Microsoft Planetary Computer, six band-math indices over an NDWI ∧ MNDWI water mask, deterministic risk scoring, Gemini 2.5 Flash narrative grounded in the numbers, branded WeasyPrint PDF reports, and a polished Next.js 15 frontend.
Pipeline
- Real Sentinel-2 L2A retrieval via Microsoft Planetary Computer STAC; signed COG reads with native-resolution alignment for the mixed 10 m / 20 m bands.
- Six band-math indices (NDWI · MNDWI · NDTI · NDCI · NDVI · WRI), masked-mean aggregated over the water polygon.
- Combined NDWI ∧ MNDWI water mask (Xu 2006) — defeats the well-known NDWI-only false positive over vegetation.
- Deterministic weighted risk model with bounded field-evidence bonus; numeric band is auditable, unit-tested, and never moved by the LLM.
- Gemini 2.5 Flash narrative bound to the deterministic numbers; automatic fallback to a second API key on quota / 429 errors; deterministic fallback for offline CI.
- Land-vs-water sanity check classifies every AOI as water · mixed · land and surfaces a prominent banner + LLM disclosure when the AOI isn't a water body.
Agent layer
- Coordinator (Gemini thinking mode) plans a workflow over four specialist agents and adapts to whether the water body has prior history.
- Scout uses Gemini function calling + multimodal vision on the real Sentinel-2 RGB thumbnail; re-queries STAC with a tighter cloud bound when Vision flags haze over the AOI.
- Historian combines Google Search grounding, URL Context, code execution (Mann-Kendall trend significance) and long-context history into a single briefing the Analyst quotes verbatim.
- Analyst drafts the narrative, runs a self-critique pass against the hard rules, and rewrites once when the critique rejects the draft.
- Reporter turns the multi-agent outputs into a structured citizen summary card (tone, guidance, limitations, and citations).
- Full per-session execution captured in agent_traces (JSONB) and surfaced in the Agent Trace UI card and the PDF appendix.
- AQUALENS_AGENTIC_MODE flag preserves the single-call deterministic narrative path for CI and offline runs.
Memory & adaptation
- agent_memory table persists Historian-distilled notes per water body across sessions — the literal 'manages multi-step tasks over time' criterion.
- text-embedding-004 vectors stored on each note (768 dims); pgvector(768) + HNSW cosine index on Postgres for fast semantic recall.
- Soft-archives older notes past 50 active rows per water body so recall queries stay focused on recent context.
- Same recall code path runs on SQLite (tests) and Postgres (production) — pgvector just makes it faster at scale.
Frontend
- Next.js 15 app router, Tailwind 4, TypeScript strict mode.
- Custom shadcn primitives hand-tuned to OKLCH design tokens, dark and light themes.
- MapLibre map with street · satellite · terrain basemaps (collapsible switcher), Nominatim place search, decimal-coords input, click-to-pin AOI.
- Animated hero, command palette (Ctrl K / Cmd K), motion system with `prefers-reduced-motion` support.
- Session detail page with synced index charts, animated risk badge, evidence timeline, AOI banner, and live processing skeletons.
- Mobile-first field-evidence companion form with EXIF-stripped photo upload and one-tap GPS capture.
- Water-bodies library with rename + cascading delete and per-AOI session history with index trends.
Reporting
- WeasyPrint + Jinja2 PDF reports with embedded matplotlib SVG charts.
- Three-column risk row (pill ‖ score ‖ urgency) with page-break-safe glossary.
- PDF re-renders on every download so template fixes ship instantly to existing sessions.
- Banner above the risk card when the AOI is mostly land — matches the in-app warning.
Platform
- FastAPI 0.115 backend with SQLModel, Alembic migrations, BackgroundTasks.
- PostgreSQL 16 + PostGIS in production, SQLite for tests via the same SQLModel metadata.
- Two Alembic migrations: 0001_initial bootstraps the schema; 0002_aoi_type adds the water-fraction / AOI-type classifier fields.
- GitHub Actions CI running ruff, black, pytest, vitest, typecheck, eslint, stylelint, and a Playwright E2E job against the compose stack.
- Docker Compose for local dev, Render Blueprint for the backend, vercel.json for the frontend.
Licensing & docs
- Code and documentation licensed under MIT.
- NOTICE.md catalogues every third-party Python and Node dependency plus the data sources.
- COMMERCIAL_LICENSE.md clarifies that MIT already permits commercial use.
- Methodology, risk model, API contract, user manual, and frontend design notes shipped under docs/.