Root cause: node:sqlite SIGSEGVs inside pager_write leave the B-tree malformed in a way that still opens but fails integrity checks; large operational-log tables widen the write window where the crash strikes. - backup: verify every copy with PRAGMA quick_check, quarantine corrupt copies as *.corrupt, and never rotate out the last verified-good backup - db: add Database.recoverIfCorrupt() startup guard (wired into TaskStore.init, disk-backed only, opt out via FUSION_DISABLE_DB_AUTORECOVER) that rebuilds a malformed db via sqlite3 .recover, preserving the corrupt original; also fixes the latent `.recover main` invalid-option bug that made recoverDatabase() always fail - db: drop lost_and_found* scratch tables on init; add pruneOperationalLogs() - settings: add operationalLogRetentionDays (default 30, 0 = off) and prune activityLog/agentLogEntries/runAuditEvents/agentHeartbeats during maintenance - dashboard: expose retention in Settings -> Backups -> Database Maintenance Tests: backup 59/59, db 135/135 (incl. real corrupt->recover->reopen), self-healing cleanup/corruption 10/10, settings 77/77, SettingsModal 460/460. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1.2 KiB
1.2 KiB
@runfusion/fusion
| @runfusion/fusion |
|---|
| minor |
Harden the project database against the recurring "database disk image is malformed" corruption.
- Integrity-checked backups: every backup copy is now verified with
PRAGMA quick_checkbefore it is kept, a verifiably-corrupt copy is quarantined as*.corruptinstead of masquerading as good, andcleanupOldBackupswill never rotate out the last verified-good backup. - Startup auto-recovery: on open, a malformed
fusion.dbis detected and rebuilt offline viasqlite3 .recover(corrupt original preserved asfusion.db.corrupt-<ts>, stale-wal/-shmdropped) before any connection is established. Opt out withFUSION_DISABLE_DB_AUTORECOVER=1. This also fixes a latent bug where the recovery path invoked the non-existent.recover mainoption and always failed. - Database shrink + retention: scratch
lost_and_found*tables left by prior recoveries are dropped on init, and a newoperationalLogRetentionDayssetting (default 30 days, configurable in Settings → Backups → Database Maintenance, 0 to disable) prunes unbounded append-only log tables (activityLog,agentLogEntries,runAuditEvents,agentHeartbeats) during periodic maintenance to curb the file growth that widens the corruption window.