doctor: add JSONL integrity check/fix and harden repairs

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
Jordan Hubbard
2025-12-26 08:18:25 -04:00
parent 1a4f06ef8c
commit 8166207eb4
10 changed files with 663 additions and 31 deletions

View File

@@ -353,9 +353,23 @@ func applyFixesInteractive(path string, issues []doctorCheck) {
// applyFixList applies a list of fixes and reports results
func applyFixList(path string, fixes []doctorCheck) {
// Run corruption recovery before any operations that need a healthy SQLite DB.
priority := map[string]int{
"Database Integrity": 0,
// Apply fixes in a dependency-aware order.
// Rough dependency chain:
// permissions/daemon cleanup → config sanity → DB integrity/migrations → DB↔JSONL sync.
order := []string{
"Permissions",
"Daemon Health",
"Database Config",
"JSONL Config",
"Database Integrity",
"Database",
"Schema Compatibility",
"JSONL Integrity",
"DB-JSONL Sync",
}
priority := make(map[string]int, len(order))
for i, name := range order {
priority[name] = i
}
slices.SortStableFunc(fixes, func(a, b doctorCheck) int {
pa, oka := priority[a.Name]
@@ -411,6 +425,8 @@ func applyFixList(path string, fixes []doctorCheck) {
err = fix.DatabaseConfig(path)
case "JSONL Config":
err = fix.LegacyJSONLConfig(path)
case "JSONL Integrity":
err = fix.JSONLIntegrity(path)
case "Deletions Manifest":
err = fix.MigrateTombstones(path)
case "Untracked Files":
@@ -711,6 +727,13 @@ func runDiagnostics(path string) doctorResult {
result.Checks = append(result.Checks, configValuesCheck)
// Don't fail overall check for config value warnings, just warn
// Check 7b: JSONL integrity (malformed lines, missing IDs)
jsonlIntegrityCheck := convertWithCategory(doctor.CheckJSONLIntegrity(path), doctor.CategoryData)
result.Checks = append(result.Checks, jsonlIntegrityCheck)
if jsonlIntegrityCheck.Status == statusWarning || jsonlIntegrityCheck.Status == statusError {
result.OverallOK = false
}
// Check 8: Daemon health
daemonCheck := convertWithCategory(doctor.CheckDaemonStatus(path, Version), doctor.CategoryRuntime)
result.Checks = append(result.Checks, daemonCheck)