feat(doctor): add database corruption recovery to --fix

Adds automatic database recovery when bd doctor --fix detects corruption:
- Detects SQLite corruption (malformed database, SQLITE_CORRUPT errors)
- Backs up corrupted database before recovery attempt
- Rebuilds from JSONL if available (issues.jsonl, deletions.jsonl)
- Falls back to fresh database if JSONL unavailable
- Reports recovery results (issues imported, success/failure)

Recovery is triggered automatically by --fix when corruption is detected.
No manual intervention required.
This commit is contained in:
Ryan Snodgrass
2025-12-26 18:55:07 -05:00
parent 9ec8fdd538
commit 721ae70ccb
5 changed files with 238 additions and 3 deletions

View File

@@ -375,6 +375,9 @@ func applyFixList(path string, fixes []doctorCheck) {
err = fix.DatabaseVersion(path)
case "Schema Compatibility":
err = fix.SchemaCompatibility(path)
case "Database Integrity":
// Corruption detected - try recovery from JSONL
err = fix.DatabaseCorruptionRecovery(path)
case "Repo Fingerprint":
err = fix.RepoFingerprint(path)
case "Git Merge Driver":
@@ -432,6 +435,10 @@ func applyFixList(path string, fixes []doctorCheck) {
// No auto-fix: compaction requires agent review
fmt.Printf(" ⚠ Run 'bd compact --analyze' to review candidates\n")
continue
case "Large Database":
// No auto-fix: pruning deletes data, must be user-controlled
fmt.Printf(" ⚠ Run 'bd cleanup --older-than 90' to prune old closed issues\n")
continue
default:
fmt.Printf(" ⚠ No automatic fix available for %s\n", check.Name)
fmt.Printf(" Manual fix: %s\n", check.Fix)
@@ -837,6 +844,12 @@ func runDiagnostics(path string) doctorResult {
result.Checks = append(result.Checks, compactionCheck)
// Info only, not a warning - compaction requires human review
// Check 29: Database size (pruning suggestion)
// Note: This check has no auto-fix - pruning is destructive and user-controlled
sizeCheck := convertDoctorCheck(doctor.CheckDatabaseSize(path))
result.Checks = append(result.Checks, sizeCheck)
// Don't fail overall check for size warning, just inform
return result
}