-
v2026.8.16
StableAll checks were successfulCI / release-scripts (pull_request) Successful in 7ssecurity-scan / SBOM (trivy) (pull_request) Successful in 10ssecurity-scan / Filesystem scan (trivy fs) (pull_request) Successful in 15ssecurity-scan / JS SCA (npm audit) (pull_request) Successful in 16ssecurity-scan / Python SAST (bandit) (pull_request) Successful in 18ssecurity-scan / Python SCA (pip-audit) (pull_request) Successful in 37stest-build / build (frontend) (pull_request) Successful in 56sCI / pre-commit (pull_request) Successful in 56sCI / frontend-test (pull_request) Successful in 1m1stest-build / build (backend) (pull_request) Successful in 1m28stest-build / build (pull_request) Successful in 0sCI / backend-test (pull_request) Successful in 2m20sCI / e2e (pull_request) Successful in 3m28sCI / release-scripts (push) Successful in 6ssecurity-scan / SBOM (trivy) (push) Successful in 10ssecurity-scan / Filesystem scan (trivy fs) (push) Successful in 14ssecurity-scan / JS SCA (npm audit) (push) Successful in 15ssecurity-scan / Python SAST (bandit) (push) Successful in 16ssecurity-scan / Python SCA (pip-audit) (push) Successful in 34sCI / pre-commit (push) Successful in 56spublish-main / build (frontend) (push) Successful in 56sCI / frontend-test (push) Successful in 1m6spublish-main / build (backend) (push) Successful in 1m10spublish-main / build (push) Successful in 0sCI / backend-test (push) Successful in 2m19sCI / e2e (push) Successful in 3m26srelease-and-deploy / release-scripts (push) Successful in 6srelease-and-deploy / release (push) Successful in 18srelease-and-deploy / pre-commit (push) Successful in 57srelease-and-deploy / frontend-test (push) Successful in 58srelease-and-deploy / build (frontend) (push) Successful in 1m9srelease-and-deploy / build (backend) (push) Successful in 1m13srelease-and-deploy / build (push) Successful in 0srelease-and-deploy / backend-test (push) Successful in 2m19srelease-and-deploy / e2e (push) Successful in 3m25srelease-and-deploy / ci (push) Successful in 0srelease-and-deploy / deploy (push) Successful in 1m49sreleased this
2026-08-16 21:02:14 +00:00 | 14 commits to main since this releaseNote when rolling out
- The migration converts
cards.source_data,cards.notesand
outgoing_posts.contentto encrypted bytea in place. Not rolling-safe:
stop the old pod before the new one boots, and take a database backup
first - reading the converted columns afterwards requires the
WAGGLE_SECRET_KEYthe migration ran with. - A second migration then strips the message, author and attachments out of
cards.source_data. One-way by design: the downgrade cannot put them back.
Link a channel with ~
- Typing
~offers your channels, most recently linked first, and inserts a
reference to the one you pick. - Channels from your other teams are in the list too, marked with their team.
They get a full link, because Mattermost only resolves a~nameinside the
team of the message. @in a new message without a recipient now says "Kies eerst een kanaal bij
Aan" rather than inviting you to keep typing.
Release notes in the app
- Returning users get a "Nieuw in Waggle" banner above every page, folded shut,
listing the releases they missed by date. Dismissing it is permanent and
follows the account, not the browser. - Every missed release is in that one expand. A button underneath fetches the
releases before them, one at a time. - Notes are Dutch markdown per release in
frontend/src/content/releases/; a
release without a file shows no banner, and a new account sees nothing. The
release job fails whileunreleased.mdhas not been renamed to its version.
Under the hood
- Message snapshots, notes and outgoing drafts are encrypted at rest:
Fernet under two new HKDF domains, covered bywaggle rotate-keys. - A card stores references only - post, channel and permalink. The message,
author and attachments come from Mattermost per request, so an edited post
no longer needs a resync and nothing of it sits in the database. - A card whose post Mattermost no longer has reads "Bericht is niet meer
beschikbaar in Mattermost" and keeps its status, planning and notes. If the
fetch itself fails, the list says so once, with "Opnieuw proberen". - Cache and log hardening: API responses default to no-store, attachments cache
only as inline images for an hour, typed search text moved from URLs into POST
bodies, and the production access log is off. - Error paths stopped echoing content: database errors hide bind parameters,
422 responses drop the submitted input, the rate limiter logs a hashed key. - Logout clears the browser's cache and storage (
Clear-Site-Data) plus
localStorage traces;sync_logsage out after 90 days. - The pod writes its own scrubbed request log (status, duration, pseudonymous
user/session ids; no IPs or query strings) and sessions record
last_seen_atfor incident reconstruction. - NLDD design system 0.8.82. Enter submits the account forms again, the
retention dropdowns are now named by the label above them instead of by a
summary that shared no words with it, and the import success notice is an
nldd-bannerrather than a hand-rolled one. - Postgres 17 digest bumped to
e384114.
Container images
- The migration converts