Documentation
Changelog
Step-by-step guide
•
Updated 24 August 2026
8.8.1
Migration is now a deliberate action, not automatic. The gateway fails closed if its database schema is not at the expected version. Run --migrate up (or apply the generated SQL by hand) before deploying this release. A security product should never silently rewrite its own schema at startup; this release makes that an explicit, operator-approved step instead. See the CLI reference for the full command set.
Detection correctness
- Risk labels no longer contradict classification. A confirmed, well-behaved bot could previously be described as "almost certainly human" in the dashboard, because the risk band's language and the bot-probability score were two independently-drifting sources of the same claim. Risk descriptions now describe activity only; classification is the single source for what something is. See the risk model for the full design.
- Several shipped policy rules were silently inert. Two default rules referenced facet names that no detector actually produced, so
PredicateEvaluatorfailed silently on an unknown facet and the rules never fired. Fixed, with a validator that now fails loudly at load time instead of silently at evaluation time. - The
allaudience filter meant two different things depending on which code path served a request, one excluded internal traffic and one didn't. Now consistent; internal traffic has an explicit, separate opt-in.
Performance and memory
- Dashboard memory footprint cut roughly 6x (3.2Gi to 543Mi under load) by replacing a stack of reactive caching layers (output cache, materializer, compression, circuit breaker) with a single streaming pipeline.
- Connection handling consolidated onto one pooled data source per process, with tuning that previously lived on a config value nothing actually read.
Dashboard
- The traffic page's endpoint list now renders on first load. It previously required an interaction to populate, showing an empty state on a fresh visit even with real traffic present.
- The managed-domains breakdown widget has been removed. It showed zero-traffic rows for entries that were never real domains and its links did not resolve correctly. Domain scoping is handled by the dashboard's domain selector, which is unaffected.
Operational visibility
- Download source liveness is now visible per fetch source in most cases: is it configured, when did it last succeed, what does it fall back to. Twelve of twenty-three sources currently share one liveness bucket rather than reporting individually; per-source resolution for that group needs a schema change and is planned for a later release. Grouped-but-honest beats per-source but fabricated.
- Backup health now asserts that a backup is restorable, not only that the write succeeded. A backup can report healthy at every write-side check and still fail to restore if its required WAL range isn't co-located with it; this release changes what "healthy" means for a backup to something a restore test actually confirms.
Known limitations in this release
- Fetch liveness is still group-level for the 12 sources noted above. Per-source resolution is planned, not silently dropped.
- The gateway's local state (fingerprint database, GeoIP data, on-disk fetch records) does not currently survive a pod restart in the reference Kubernetes deployment, which has no persistent volume claim for it. Deriving fetch-source liveness from file modification time works around part of this; the underlying gap remains and a persistent-volume fix is planned.
- A full end-to-end restore from a rehomed backup target has not yet completed, though the restore command itself and the backup chain are both proven. Treat backup recoverability on freshly-migrated infrastructure as unverified until a full restore is demonstrated.