microclimate-x / CHANGELOG.md
W1nd5pac's picture
Deploy 2026-05-20T06:52:08Z β€” 11e81c5
4eefabb verified

Changelog

All notable changes to this project will be documented in this file. Format follows Keep a Changelog; versioning follows Semantic Versioning.


[1.0.0] β€” 2026-05-11

The first complete release. Engineering-grade hardening across backend, ML pipeline, frontend, and DevOps; the rule engine is fully aligned with the D5 thesis proposal Β§3.7 / P4.

Added β€” Backend

  • Request-ID middleware that stamps every response with X-Request-ID and X-Response-Time-ms. Incoming X-Request-ID headers propagate end to end, enabling cross-service tracing.
  • Centralised error contract (backend/errors.py) β€” every non-2xx response is a typed ErrorResponse { error, detail, request_id, context } JSON document; no bare 500-HTML responses leak.
  • Structured logging with per-request log records (request_id field on every line, ISO-8601 timestamps).
  • Enriched /api/health reporting uptime, cache row counts (live / expired / total), DB size, and inference-log size.
  • /api/version endpoint returning version + git short SHA + ML feature schema.
  • Cache hygiene β€” prune_expired() runs on startup, sweeps inference-log rows older than 7 days, and cache_stats() is exposed via /api/health.
  • Fire-and-forget cache writes with the task reference retained (asyncio.create_task lint compliance).
  • Defensive ML engine β€” predict_rain_probability always returns float ∈ [0, 1]; NaN/Inf/wrong-type feature values gracefully degrade; model-load failures fall through to the heuristic instead of crashing.
  • Improved heuristic fallback β€” now also responds to pressure_change_3h so the "no model yet" demo still behaves sensibly.
  • Terrain edge cases β€” antimeridian wrap, polar clamp, ocean / no-data DEM cells handled instead of raising obscure type errors.

Added β€” Rule Engine (already shipped, now fully tested)

  • 4 sub-hazard scorers β€” rainfall / fog / wind gust / thunderstorm.
  • D5 Β§3.7.2 R1-R4 Decision Table.
  • Activity-aware weighted composite (hiker | driver | construction | general).
  • Dominant-hazard composite formula: 0.80Β·max + 0.20Β·mean(rest).

Added β€” ML pipeline

  • scripts/4_evaluate_model.py generating publication-quality figures (ROC + AUC, PR + AP, calibration / Brier, threshold sweep, top-20 feature importance, confusion matrix at F2-optimal threshold).
  • figures/evaluation_summary.json machine-readable evaluation blob for the thesis appendix.
  • figures/threshold_sweep.csv for full reproducibility of the precision-recall trade-off table.
  • models/MODEL_CARD.md β€” HuggingFace-style model card with intended use, training data, evaluation, limitations, and ethical considerations.

Added β€” Tests

  • HTTP integration tests with respx-mocked external APIs (tests/test_api.py): happy path, cache hit, distinct cache slot per activity, invalid input β†’ 422, upstream failure β†’ 502, CORS, OpenAPI schema.
  • Cache layer tests (tests/test_cache.py): TTL, expiry, prune, stats.
  • Terrain edge-case tests (tests/test_terrain_edge.py): antimeridian, polar clamp, malformed DEM.
  • ML engine tests (tests/test_ml_engine.py): unloaded behaviour, heuristic monotonicity, NaN/None resilience.
  • Session-scoped conftest.py sets an isolated MICROCLIMATEX_DB for every test run (no clobbering the dev cache).
  • Total: 70 tests; backend coverage 97 %.

Added β€” Frontend

  • Activity selector (Hiker / Driver / Construction / General) with localStorage persistence and keyboard accessibility (aria-pressed
    • focus-visible).
  • 4 mini-gauges for the per-hazard sub-scores, each with a tooltip explaining what drives it.
  • D5 Β§3.7.2 R1-R4 indicator badges (highlight when fired).
  • Demo scenarios dropdown (Genting Β· Cameron Β· Kinabalu Β· Everest Β· Singapore).
  • Loading spinner during in-flight requests.
  • Toast notification for errors and "no model loaded" warnings.
  • Map layer switcher β€” Dark base + Topographic option.
  • Bilingual EN/ZH UI persisted across reloads.

Added β€” DevOps / Reproducibility

  • GitHub Actions CI (.github/workflows/ci.yml) β€” pytest matrix on Python 3.9 / 3.11 / 3.12, ruff lint, coverage XML artefact, plus a Docker image-build smoke test with Buildx + GHA cache.
  • Multi-stage Dockerfile β€” builder stage for wheels, slim runtime with a non-root mcx user, baked-in HEALTHCHECK against /api/health.
  • docker-compose.yml with a named data volume.
  • Makefile β€” single-word recipes for install, test, lint, run, synth, preprocess, train, evaluate, docker, clean.
  • requirements-dev.txt β€” split dev tooling (pytest-cov, ruff, respx, matplotlib) from runtime requirements.
  • pyproject.toml β€” ruff configuration + pytest config.
  • .pre-commit-config.yaml β€” trailing-whitespace, end-of-file, YAML/JSON/TOML checks, large-file guard, ruff lint + format.
  • .dockerignore keeping the image lean.

Added β€” Documentation

  • docs/architecture.md β€” P4.1 β†’ P4.6 internal flow + dominant-hazard formula rationale.
  • docs/thresholds.md β€” every threshold cited; new Β§8-Β§12 for the four hazard categories, R1-R4 table, and activity-weight matrix.
  • docs/dataset.md β€” formal target definition (is_rain_event) and train/test split rationale.

Changed

  • Rainfall sub-scorer calibration β€” 45 % macro probability now lands at ~ 40 (Caution band), matching the proposal's intent.
  • Composite-score formula switched from naive arithmetic mean to dominant-hazard + secondary to avoid mean dilution.
  • Cache key now incorporates activity β€” different weights β†’ different composite β†’ must not share a slot.

Fixed

  • tenacity.RetryError from the retry decorator was not caught by the except httpx.HTTPError clause, producing a misleading 500. Now caught alongside httpx.HTTPError and ValueError, returning a clean 502.

[0.2.0] β€” 2026-05-11

Initial D5-alignment pass β€” see commit 55fd759.

[0.1.0] β€” 2026-05-11

Project scaffolding and Hybrid Engine v1 β€” see commits b218f5b through 4639890.