-
v4.0.1
StableAll checks were successfulCI / Frontend tests, audit, and build (push) Successful in 1m18sCI / Backend lint (ruff) (push) Successful in 33sCI / Docker image build (push) Successful in 13sRelease / Create Forgejo release (push) Successful in 19sCI / Bot/backend version sync (push) Successful in 59sCI / Summarisation accuracy eval harness (stub provider) (push) Successful in 2m41sRelease / Build and push versioned images (push) Successful in 1m26sCI / Backend migration, tests, and audit (push) Successful in 4m54sCI / Bot tests and audit (push) Successful in 4m38sreleased this
2026-08-29 07:01:42 +00:00 | 407 commits to main since this releaseRaw audio is never destroyed without a recovery window, and the secrets at
rest are both readable and actually encrypted.No migrations. Nothing to rehearse, nothing to back out.
⚠️ Rebuild, do not pull. The backend image changes (it now pins its
PostgreSQL client to the database's major version), so deploy with
docker compose up -d --build. A pull-and-restart will not apply it.⚠️ Audio now occupies disk for longer. Every retention mode reaches
deletion through the trash, so audio survives its retention window plus the
trash grace (minimum 7 days) rather than being removed the moment the window
expires. Under the previous default it was deleted during processing and
occupied nothing at all.If the startup log names a setting as having been stored in plaintext,
rotate that credential. Re-encrypting protects it going forward; it does not
un-expose a value that was already readable in every backup taken until then.Security
- Sensitive settings stored in plaintext are now encrypted on startup.
Encryption only ever happened on write, and rows written before it was
introduced were passed through on read forever — so a credential that had
never been rotated since could still be sitting in clear text in the database
and in every backup, with nothing reporting it. Any such row is re-encrypted
at startup and logged by name. If a row is reported, rotate that credential
— it was readable in every backup taken until now.
Fixed
-
Database backups are restorable again. The backup ran
pg_dumpfrom the
backend image while a restore runspg_restoreagainst the database image,
and the two were on different major versions — so every dump was rejected by
the server's own tooling withunsupported version (1.16) in file header,
while the job reported success and recorded it as one. The backend image now
pins its client to the database's major version, a test asserts the two stay
in step, and the backup refuses to run rather than writing a dump it knows
cannot be restored. Existing dumps written before this are not restorable
without a matching newer client — replace them by taking a fresh backup
after upgrading.
crashes on first use.** Sensitive settings are encrypted with a key derived
fromSECRET_KEY, which lives in.envand is not part of a database dump —
so restoring elsewhere left them unreadable, and reading one raised a raw
cryptography error out of the settings layer instead of taking the
"not configured" path every caller already handles. Unreadable settings now
degrade to unconfigured, are reported once and clearly, and are listed at
startup so the problem is found during the restore rather than days later
when a session fails to summarise.docs/OPERATIONS.mdnow states that
SECRET_KEYmust be backed up alongside the database. -
Admin can distinguish "never configured" from "configured but
unreadable". They render identically in every settings form, which is how a
restore produced a system that looked complete and was not. -
Raw audio is no longer deleted the moment a transcript exists. The
recommended retention mode destroyed the per-speaker WAVs inline during
processing, on the reasoning that there was nothing left to reprocess. That is
wrong in the case that matters, because the pipeline itself changes: v4.0.0
rewrote transcription, extraction, validation and composition, and no real
recording survived to validate any of it against. The mode is now
trash_after_processing— the audio moves to the trash, stays recoverable
there, and is deleted only once the grace has elapsed. The old
delete_after_processingname is still accepted from existing configuration
and normalised on read, so no action is needed on upgrade. -
The trash grace is a floor, not a default. A configured value below seven
days is clamped up, so a misconfiguration cannot reintroduce same-day loss. -
An expiring retention window no longer deletes directly. Under
retain_daysthe sweeper now moves expired audio to the trash rather than
removing it, so every mode reaches deletion through the same recoverable
window. Audio therefore lives for the configured window plus the trash
grace — budget disk accordingly. -
A trashed recording is no longer deleted early by the retention window.
The grace-period sweep and the policy sweep raced, and the shorter one won: a
recording trashed today, whose window had already passed, was removed on the
next scheduled run without its grace ever being observed. -
A silent speaker is no longer reported as having spoken. The fix that was
supposed to report a backend-dropped silent track as present-but-uncaptured
was overridden, because the same person was still counted among the captured
speakers and that assignment won. It only affected recordings the current bot
did not produce — which is precisely the case the guard existed for.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Sensitive settings stored in plaintext are now encrypted on startup.