• v1.2.0 09add453bf

    v1.2.0 — Notification formatting & delivery reliability
    All checks were successful
    CD / test (push) Successful in 3m48s
    CD / deploy (push) Successful in 23s
    Stable

    claude-bot released this 2026-07-18 22:16:14 +00:00 | 140 commits to main since this release

    Hardens the notification path end-to-end and adds new channels/UX. 12 issues across three phases. No breaking changes; several features are opt-in.

    Delivery reliability

    • Delivery outbox (#50) — NWS-warning delivery is now at-least-once: a notification_deliveries table + a retry job with bounded exponential backoff, and notifiers that raise classified Transient/Permanent errors so real transient failures are actually retried (never re-sending a delivered alert). The milestone's keystone.
    • Pipeline lifecycle hardening (#53) — clear-path row locks (no double all-clears), tracked/drained background tasks, and a single shared SSE LISTEN broker instead of one Postgres connection per client.
    • NWS CAP fallback (#78) — fall back to the CAP ATOM feed when the primary alerts API fails.
    • Warning acknowledgement + escalation (#81, opt-in) — re-notify active, unacknowledged warnings on an interval until acknowledged (bounded), reusing the outbox.

    Channels & UX

    • Email / SMTP channel (#80).
    • Temporary location snooze / mute (#82).
    • End-to-end pipeline drill (#86) — admin endpoint that injects a synthetic alert through the real pipeline.
    • Shared formatter migration (#14, #15) — the six richer channels now use per-channel budgets + one compact "Details" link.
    • Segment-aware SMS budgeting (F-32) — non-GSM-7 characters no longer cause silent extra segments.
    • Redirect-token short links (#13, opt-in) — open-redirect-safe {base}/r/{token} via SHORT_LINK_REDIRECT_MODE.
    • Per-type channel-config validation (#55) — malformed config is rejected at create/update (422) instead of crashing a send.
    • Non-blocking Twilio + TimezoneFinder singleton (#56).

    Testing

    Full suite green on the dev server: 635 passed (incl. a Postgres integration tier). Migrations 00190023 apply cleanly to head on real Postgres. The outbox retry acceptance is covered end-to-end (transient failure → later successful delivery; permanent → dead; no duplicates).

    New config (all optional, safe defaults)

    SMTP_*/EMAIL_ENABLED, NWS_CAP_FALLBACK_ENABLED, DELIVERY_*, SSE_CLIENT_QUEUE_MAXSIZE, ESCALATION_* (off by default), SHORT_LINK_REDIRECT_MODE, SHORT_LINK_EXTERNAL_ALLOWLIST. See .env.example.

    Full changelog: CHANGELOG.md. PRs #99–#103.

    Downloads
  • v1.1.0 c4fbeb4a7c

    v1.1.0 — Operations, observability & CD
    All checks were successful
    CD / test (push) Successful in 2m51s
    CD / deploy (push) Successful in 19s
    Stable

    claude-bot released this 2026-07-18 18:25:57 +00:00 | 150 commits to main since this release

    Operations, observability, CI/CD, and data-lifecycle release — the health-and-hardening milestone from the 2026-07-17 audit. 15 issues across four phases. No breaking changes except the loopback-bind default (see below).

    Observability

    • Prometheus /metrics (#73) — per-feed freshness, failure counts, up-state, 24h event counts; optional bearer token.
    • Poller heartbeat / dead-man's-switch (#77) — in-app watchdog + optional external heartbeat ping.
    • Proactive stale/failing-product alerting (#8) — admin webhook alerts (debounced).
    • Degraded-data dashboard banner (#74) and 48h freshness trend sparklines on /diagnostics (#9).

    Operations & data lifecycle

    • Public Link Admin Console (#7) — list/filter/copy/open/revoke public links.
    • /p/* rate limiting (#10), default SMS public links (#11).
    • Data-retention cleanup jobs (#52) — long, config-backed windows; MCD rows now expire; radar cache pruned.
    • Config export/import (#79) — admin JSON backup/restore of locations, channels, subscriptions.
    • Postgres backups (#67) — scripts/backup.sh + opt-in db-backup profile + documented restore.

    Infrastructure & CI/CD

    • Container hardening (#64) — runs non-root (gosu entrypoint), URL-encoded DSN, healthchecks, configurable mem_limit. ⚠️ The app now binds to 127.0.0.1 by default — set APP_BIND=0.0.0.0 (or front it with a TLS reverse proxy) to expose it.
    • CD rollback (#66) — a failed dev deploy restores the last-working commit; manual prod procedure documented.
    • CI hardening (#65, #68) — ruff, alembic upgrade head on real Postgres, a Postgres integration test tier, and advisory pip-audit.

    Notes

    • pip-audit is advisory pending the Renovate dependency upgrades (#30–#37).
    • Retention windows are deliberately long — the planned v2.0.0 Historical Weather Event Explorer (#22) will consume that history.
    • New .env settings (all optional, safe defaults): APP_BIND, APP_MEM_LIMIT, METRICS_*, ADMIN_ALERT_WEBHOOK, HEARTBEAT_*, STALE_PRODUCT_ALERT_MINUTES, SMS_DEFAULT_PUBLIC_LINKS, PUBLIC_RATE_LIMIT_*, RETENTION_*, RADAR_CACHE_RETENTION_DAYS, BACKUP_*. See .env.example.

    Full test suite green (489 tests incl. a Postgres tier). PRs #94–#98.

    Full changelog: see CHANGELOG.md.

    Downloads
  • v1.0.3 ce5402fef4

    v1.0.3 — Security hardening
    All checks were successful
    CD / test (push) Successful in 2m22s
    CD / deploy (push) Successful in 24s
    Stable

    claude-bot released this 2026-07-18 14:28:31 +00:00 | 163 commits to main since this release

    Patch release: security hardening. Closes the security findings from the 2026-07-17 codebase audit. Behaviour-preserving where possible.

    Security

    • Reject placeholder SECRET_KEY (#45) — the example key no longer passes production validation; rejected in every environment; dev uses an ephemeral key with a warning.
    • Stop voip.ms credential leakage (#46) — credentials moved to the POST body, a scrub_secrets() pass redacts all persisted notifier errors, and httpx request logging is quieted. ⚠️ Rotate the voip.ms API password after upgrading.
    • Redact channel config secrets in API responses (#47) — secret-bearing keys are redacted; full config only for users who can manage the channel.
    • Resolve DNS in webhook SSRF validation (#51) — validation resolves and rejects private/loopback/reserved addresses; sends pin the connection to the validated IP (Host/SNI preserved).
    • Vendor frontend assets (#59) — htmx, htmx-SSE, and Leaflet are served locally instead of from the unpkg CDN.
    • Public-surface privacy (#60) — no exact coordinates on the public page; the NWS public route honours public_enabled; disabling sharing revokes the location's NWS tokens immediately.
    • API hardening bundle (#70) — OIDC nonce validation; CSRF-protected POST logout; media cache-key validation + path containment; excluded_event_types persisted on create.

    Full test suite green (417 passed) including new regression tests across all fix areas.

    ⚠️ Operational follow-up

    Rotate the voip.ms API password — it may already be present in historical logs/DB.

    Full changelog: see CHANGELOG.md. PR #93.

    Downloads
  • v1.0.2 53240035f3

    v1.0.2 — Alert correctness & integrity
    All checks were successful
    CD / test (push) Successful in 3m44s
    CD / deploy (push) Successful in 1m0s
    Stable

    claude-bot released this 2026-07-18 14:28:31 +00:00 | 171 commits to main since this release

    Patch release: alert-pipeline correctness and integrity. Bug fixes only, no new features. Addresses the highest-severity findings from the 2026-07-17 codebase audit.

    Fixed

    • False all-clears on transient NWS outages (#40) — fetches retry with jittered backoff and return None on failure; a failed cycle performs no clearing or dispatch. An empty resolved-locations list can no longer mass-clear, and alerts with no ends/expires get a synthetic expiry so they stay visible and clearable.
    • Dropped alerts during large outbreaks (#41)/alerts/active responses are now paginated (bounded, logged) instead of truncated to page one and then cleared as "disappeared".
    • SPC Day 1/2/3 collapsed into one notification (#42) — convective outlooks record and dispatch per day.
    • MCD state false-positives (#43) — state matching parses the AREAS AFFECTED line, so "in"/"or" no longer match Indiana/Oregon.
    • Duplicate SPC notifications on reissuance (#44) — a same-risk reissue is treated as a continuation instead of a new outlook.
    • Alert history lost on channel deletion (#48) — deleting a channel preserves its sent_alerts rows as dashboard-only records.
    • Public location page stuck on "Loading alerts…" (#49) — current active alerts are server-rendered with a "No active alerts" empty state.
    • Details-link failures could drop notifications (#54) — all six notifier channels now send without a link on failure.
    • One malformed SPC feature aborted the whole poll (#62) — per-feature parsing and the SPC gathers are now failure-tolerant.

    Full test suite green (344 passed) including new regression tests across all fix areas.

    Full changelog: see CHANGELOG.md. PR #92.

    Downloads
  • v1.0.1 19b23f6a13

    v1.0.1
    All checks were successful
    CI / test (push) Successful in 2m43s
    Stable

    rbrooks released this 2026-06-24 00:41:53 +00:00 | 182 commits to main since this release

    Maintenance, CI, and test-hygiene release. No application/runtime behavior changes — safe to deploy with no migration or config impact.

    Added

    • CI — Forgejo Actions pipeline (.forgejo/workflows/ci.yml) runs compileall + pytest on Python 3.12 for every push and PR to main. main branch protection now requires the check before a PR can merge.
    • Renovate — auto-merge low-risk test-dependency updates (patch/pin/digest of requirements-test.txt) once CI passes.

    Fixed

    • Tests are isolated from any ambient .env, so the suite is environment-independent (previously a host .env could fail config tests and flip feature flags).
    • Eliminated a coroutine ... never awaited RuntimeWarning by mocking db.begin_nested() as an async context manager.
    • Added .pytest_cache/ to .gitignore.

    Notes

    • Verified no remaining deprecations on the pinned stack: Starlette TemplateResponse already migrated (#4); no pytest-asyncio deprecation warnings on pytest 9 / Python 3.12 (#5, #6).

    Completes the v1.0.1 — Maintenance & deprecations (+ CI) milestone (#3, #4, #5, #6).

    Downloads
  • v1.0.0 652ab3b05f

    v1.0.0 Stable

    rbrooks released this 2026-06-23 23:22:59 +00:00 | 190 commits to main since this release

    First tagged release — establishes the SemVer baseline.

    This release contains the full feature set shipped to date:

    • NWS alerts — state-batched polling, zone/polygon matching, dedup, lifecycle (updates, cancel, expire, lifted/all-clear), quiet hours.
    • SPC — convective (Day 1–3), fire, and MCD notifications; Day 4–8 awareness; SPC outlook impact pages (authenticated + reduced public views) through Phase 5.
    • Public alert detail pages/p/{token} resolver for NWS alert and SPC outlook targets, compact/short links for SMS and richer channels.
    • AI summarization — phases 1–3: provider registry with local/OpenAI-compatible/Anthropic adapters, fallback orchestration, structured context, source-grounded summaries, deterministic validators, cloud-safe metadata controls.
    • Notification channels — Discord, Matrix, Signal, SMS (Twilio), Webhook, Pushover, Webex.
    • Forecast digests, product freshness/observability diagnostics, dashboard live (SSE) refresh.
    • Security hardening — OIDC state/ID-token verification, centralized authorization, CSRF, webhook SSRF protection, production startup validation.

    See CHANGELOG.md for the detailed history. Subsequent work is tracked via versioned milestones (v1.0.1 → v2.0.0) and issues.

    Downloads