docs: backup system audit, code path findings with questions for measurement
feat(i18n): fail the release on new hard-coded UI text
fix(security-advisor): show the CVE and PHP hints, the scope note and the RFC line in the viewer's language
docs(notes): the demo on stable 2.10.9, with the rendered Security Advisor checked and the worker heal compared
Merge: the backup fixes from the audit — locks, hanging runs, room on disk, panel state
fix(backup): PostgreSQL dumps reach psql through stdin, a key that does not fit an existing repository is named, a failed panel-state run shows as a failure, an unknown database name is reported
fix(backup): the panel state holds roles and the platform's own databases, not the customers' data
docs(notes): measure the backup restore fixes and the panel-state backup on the test box
fix(backup): panel state, node state and the recovery flows work on disk too, and reserve their room first
fix(backup): the lock inspection calls get the same wait bound as the other restic calls
docs(changelog): add the testing pill for v2026.10.07.04
fix(backup): a locked-repository error tells the operator what to do, and a reworded restic retry message is reported instead of silently disabling the stall rule
fix(backup): database dumps go to disk instead of RAM, the room is reserved before the first dump for every target, and a prune keeps a reserve
fix(backup): a run retrying a failing backend is stopped within minutes, the short restic calls are bounded and the agent caps parallel runs
fix(backup): a repository lock is removed only when no process can still hold it
Merge: the rest of the backup audit — what a restore may write, what a dump may do, and what gets deleted
feat(backup): a queued or running backup can be canceled, ends as canceled instead of failed, and is on record
fix(backup): a restore is watched for stalls, waits for live locks and reads restic's summary
fix(backup): destroying or shortening a backup is on record, and lowering the retention below what exists needs a confirmation
fix(backup): an older panel's database restore is refused with the reason instead of leaving a database nobody can open
fix(backup): a schedule's hour is read in the panel host's time zone instead of UTC
fix(backup): database dumps carry routines and events, and PostgreSQL privileges granted to the customer's own roles come back
fix(backup): a database dump is imported behind the client's sandbox, under an account that reaches one database, and with the owner decided by the panel
fix(backup): a scope with nothing to back up ends quietly instead of as a failed run
fix(backup): a schedule's retention counts only its own planned runs, back up now keeps a pool of its own, and older snapshots are listed instead of silently outliving the rule
fix(backup): the platform's global sieve script is no longer part of a customer's snapshot
docs(backup): measure the retention of mixed manual and scheduled runs, and note what a mixed fleet does during the restore-bound rollout
fix(backup): a customer's restore writes only that customer's own files, and a restored config that fails its test is rolled back
fix(backup): a run that left databases out is incomplete instead of success, and a restore no longer suppresses the day's planned backup
feat(backup): a restore reports its outcome as stable codes the panel can translate
feat(backup): a job also reports what the run backed up, next to the repository growth
docs(backup): measure the cold maildir scan against the quiet-window rule
fix(backup): a blackholed target is cut off after a quiet window, CPU alone no longer counts as life
docs: the target-change note records the decided path rule, the closed applyUpdate finding and the worker test gap
fix(backup): a target change is judged on the resulting schedule and the operator's credentials go only to the operator's host; restore and browse inputs are checked where they are used
docs: say what the a11y gate does not look at
feat(backup): schedules name their time zone with a one-time notice, lowering the retention needs a typed confirmation, new restore codes
fix(ui): a failed user list, cache status or app restart says so instead of looking empty or done
fix(ui): a delete or mail-migration status poll that can no longer be answered ends with a sentence instead of running forever
docs(backup): say why the legacy snapshots are counted from the list
feat(backup): snapshots show their retention pool, older unassigned ones are listed apart with per-snapshot delete, job status 'nothing' is neutral
feat(backup): config parts of a restore report are named and say they were rolled back
feat(backup): an incomplete run sits between success and failure and names what is missing, prune_failed is no longer shown as pending
docs(audit): record the fixes for backup audit findings E, F, A, I, J
fix(backup): reject a weak fallback repo key, mask the S3 access key, redact job errors for customers
fix(backup): reject flag-shaped browse paths and bound full-restore to known backup directories
stable: release v2.10.10 (current code)
feat(backup): a run shows what it backed up and what it added, a restore that stopped says which databases are back
docs(notes): measure the backup locks, hanging runs, disk room and panel state of the testing build on the test box
docs(notes): what the backup size label and the restore report need from the API