refactor: remove all deletions.jsonl code (bd-fom)

Complete removal of the legacy deletions.jsonl manifest system.
Tombstones are now the sole deletion mechanism.

Removed:
- internal/deletions/ - entire package
- cmd/bd/deleted.go - deleted command
- cmd/bd/doctor/fix/deletions.go - HydrateDeletionsManifest
- Tests for all removed functionality

Cleaned:
- cmd/bd/sync.go - removed sanitize, auto-compact
- cmd/bd/delete.go - removed dual-writes
- cmd/bd/doctor.go - removed checkDeletionsManifest
- internal/importer/importer.go - removed deletions checks
- internal/syncbranch/worktree.go - removed deletions merge
- cmd/bd/integrity.go - updated validation (warn-only on decrease)

Files removed: 12
Lines removed: ~7500

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-16 14:20:32 -08:00
parent e0528de590
commit 9f76cfda01
32 changed files with 298 additions and 7534 deletions

View File

@@ -164,62 +164,17 @@ func TestValidatePreExportSuite(t *testing.T) {
}
func TestValidatePostImport(t *testing.T) {
t.Run("issue count decreased with no deletions fails", func(t *testing.T) {
// Note: With tombstones as the deletion mechanism, validatePostImport
// no longer fails on decreases - it only warns. The deletions.jsonl
// validation has been removed.
t.Run("issue count decreased warns but succeeds", func(t *testing.T) {
tmpDir := t.TempDir()
jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
// No deletions.jsonl file exists
err := validatePostImport(10, 5, jsonlPath)
if err == nil {
t.Error("Expected error for decreased issue count with no deletions, got nil")
}
if err != nil && !strings.Contains(err.Error(), "no deletions recorded") {
t.Errorf("Expected 'no deletions recorded' error, got: %v", err)
}
})
t.Run("issue count decreased within deletion count succeeds", func(t *testing.T) {
tmpDir := t.TempDir()
jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
deletionsPath := filepath.Join(tmpDir, "deletions.jsonl")
// Create deletions file with 5 deletions
deletionsContent := `{"id":"del-1","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-2","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-3","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-4","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-5","ts":"2024-01-01T00:00:00Z","by":"test"}
`
if err := os.WriteFile(deletionsPath, []byte(deletionsContent), 0600); err != nil {
t.Fatalf("Failed to write deletions file: %v", err)
}
// Decrease of 5 matches the 5 recorded deletions
// With tombstone-based deletions, decreases are allowed (just warn)
err := validatePostImport(10, 5, jsonlPath)
if err != nil {
t.Errorf("Expected no error when decrease matches deletions, got: %v", err)
}
})
t.Run("issue count decreased exceeding deletion count fails", func(t *testing.T) {
tmpDir := t.TempDir()
jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
deletionsPath := filepath.Join(tmpDir, "deletions.jsonl")
// Create deletions file with only 2 deletions
deletionsContent := `{"id":"del-1","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-2","ts":"2024-01-01T00:00:00Z","by":"test"}
`
if err := os.WriteFile(deletionsPath, []byte(deletionsContent), 0600); err != nil {
t.Fatalf("Failed to write deletions file: %v", err)
}
// Decrease of 5 exceeds the 2 recorded deletions
err := validatePostImport(10, 5, jsonlPath)
if err == nil {
t.Error("Expected error when decrease exceeds deletions, got nil")
}
if err != nil && !strings.Contains(err.Error(), "exceeds") {
t.Errorf("Expected 'exceeds' error, got: %v", err)
t.Errorf("Expected no error (just warning) for decreased count, got: %v", err)
}
})
@@ -243,79 +198,25 @@ func TestValidatePostImport(t *testing.T) {
}
func TestValidatePostImportWithExpectedDeletions(t *testing.T) {
// Note: With tombstones as the deletion mechanism, validatePostImportWithExpectedDeletions
// no longer fails on decreases - it only warns. The deletions.jsonl validation has been removed.
t.Run("decrease fully accounted for by expected deletions succeeds", func(t *testing.T) {
tmpDir := t.TempDir()
jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
// No deletions.jsonl needed - expected deletions from sanitize step
err := validatePostImportWithExpectedDeletions(26, 25, 1, jsonlPath)
if err != nil {
t.Errorf("Expected no error when decrease matches expected deletions, got: %v", err)
}
})
t.Run("decrease exceeds expected deletions but within manifest succeeds", func(t *testing.T) {
t.Run("decrease exceeds expected deletions warns but succeeds", func(t *testing.T) {
tmpDir := t.TempDir()
jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
deletionsPath := filepath.Join(tmpDir, "deletions.jsonl")
// Create deletions file with 3 deletions
deletionsContent := `{"id":"del-1","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-2","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-3","ts":"2024-01-01T00:00:00Z","by":"test"}
`
if err := os.WriteFile(deletionsPath, []byte(deletionsContent), 0600); err != nil {
t.Fatalf("Failed to write deletions file: %v", err)
}
// Decrease of 5, expected 2, remaining 3 covered by manifest
// Decrease of 5, expected 2 - used to fail, now warns
err := validatePostImportWithExpectedDeletions(20, 15, 2, jsonlPath)
if err != nil {
t.Errorf("Expected no error when decrease covered by expected + manifest, got: %v", err)
}
})
t.Run("decrease exceeds expected and manifest fails", func(t *testing.T) {
tmpDir := t.TempDir()
jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
deletionsPath := filepath.Join(tmpDir, "deletions.jsonl")
// Create deletions file with only 1 deletion
deletionsContent := `{"id":"del-1","ts":"2024-01-01T00:00:00Z","by":"test"}
`
if err := os.WriteFile(deletionsPath, []byte(deletionsContent), 0600); err != nil {
t.Fatalf("Failed to write deletions file: %v", err)
}
// Decrease of 10, expected 2, remaining 8 exceeds 1 in manifest
err := validatePostImportWithExpectedDeletions(20, 10, 2, jsonlPath)
if err == nil {
t.Error("Expected error when decrease exceeds expected + manifest, got nil")
}
if err != nil && !strings.Contains(err.Error(), "exceeds") {
t.Errorf("Expected 'exceeds' error, got: %v", err)
}
})
t.Run("zero expected deletions falls back to manifest check", func(t *testing.T) {
tmpDir := t.TempDir()
jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
deletionsPath := filepath.Join(tmpDir, "deletions.jsonl")
// Create deletions file with 5 deletions
deletionsContent := `{"id":"del-1","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-2","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-3","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-4","ts":"2024-01-01T00:00:00Z","by":"test"}
{"id":"del-5","ts":"2024-01-01T00:00:00Z","by":"test"}
`
if err := os.WriteFile(deletionsPath, []byte(deletionsContent), 0600); err != nil {
t.Fatalf("Failed to write deletions file: %v", err)
}
// Same as validatePostImport: decrease of 5 covered by 5 in manifest
err := validatePostImportWithExpectedDeletions(10, 5, 0, jsonlPath)
if err != nil {
t.Errorf("Expected no error when decrease matches manifest with zero expected, got: %v", err)
t.Errorf("Expected no error (just warning) for decreased count, got: %v", err)
}
})