CRITICAL: Disable export deduplication (bd-160)
The timestamp-only deduplication feature causes data loss when export_hashes table gets out of sync with JSONL file (after git operations, imports, etc). This leads to exports skipping issues that aren't actually in the file. Symptoms we saw: - Export reports 'Skipped 128 issues with timestamp-only changes' - JSONL only has 38 lines but DB has 149 issues - Two repos on same commit show different issue counts - Auto-import doesn't trigger (hash matches despite missing data) Fix: Disable the feature entirely until we can implement proper JSONL integrity validation (see bd-160 for proposed solutions).
This commit is contained in:
@@ -454,43 +454,40 @@ func writeJSONLAtomic(jsonlPath string, issues []*types.Issue) ([]string, error)
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Write all issues as JSONL (with timestamp-only deduplication for bd-159)
|
// Write all issues as JSONL (timestamp-only deduplication DISABLED - bd-160)
|
||||||
ctx := context.Background()
|
|
||||||
encoder := json.NewEncoder(f)
|
encoder := json.NewEncoder(f)
|
||||||
skippedCount := 0
|
skippedCount := 0
|
||||||
exportedIDs := make([]string, 0, len(issues))
|
exportedIDs := make([]string, 0, len(issues))
|
||||||
|
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
// Check if this is only a timestamp change (bd-159)
|
// DISABLED: timestamp-only deduplication causes data loss (bd-160)
|
||||||
skip, err := shouldSkipExport(ctx, issue)
|
// skip, err := shouldSkipExport(ctx, issue)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
// Log warning but continue - don't fail export on hash check errors
|
// if os.Getenv("BD_DEBUG") != "" {
|
||||||
if os.Getenv("BD_DEBUG") != "" {
|
// fmt.Fprintf(os.Stderr, "Debug: failed to check if %s should skip: %v\n", issue.ID, err)
|
||||||
fmt.Fprintf(os.Stderr, "Debug: failed to check if %s should skip: %v\n", issue.ID, err)
|
// }
|
||||||
}
|
// skip = false
|
||||||
skip = false
|
// }
|
||||||
}
|
// if skip {
|
||||||
|
// skippedCount++
|
||||||
if skip {
|
// continue
|
||||||
skippedCount++
|
// }
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := encoder.Encode(issue); err != nil {
|
if err := encoder.Encode(issue); err != nil {
|
||||||
return nil, fmt.Errorf("failed to encode issue %s: %w", issue.ID, err)
|
return nil, fmt.Errorf("failed to encode issue %s: %w", issue.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save content hash after successful export (bd-159)
|
// DISABLED: export hash tracking (bd-160)
|
||||||
contentHash, err := computeIssueContentHash(issue)
|
// contentHash, err := computeIssueContentHash(issue)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if os.Getenv("BD_DEBUG") != "" {
|
// if os.Getenv("BD_DEBUG") != "" {
|
||||||
fmt.Fprintf(os.Stderr, "Debug: failed to compute hash for %s: %v\n", issue.ID, err)
|
// fmt.Fprintf(os.Stderr, "Debug: failed to compute hash for %s: %v\n", issue.ID, err)
|
||||||
}
|
// }
|
||||||
} else if err := store.SetExportHash(ctx, issue.ID, contentHash); err != nil {
|
// } else if err := store.SetExportHash(ctx, issue.ID, contentHash); err != nil {
|
||||||
if os.Getenv("BD_DEBUG") != "" {
|
// if os.Getenv("BD_DEBUG") != "" {
|
||||||
fmt.Fprintf(os.Stderr, "Debug: failed to save export hash for %s: %v\n", issue.ID, err)
|
// fmt.Fprintf(os.Stderr, "Debug: failed to save export hash for %s: %v\n", issue.ID, err)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
exportedIDs = append(exportedIDs, issue.ID)
|
exportedIDs = append(exportedIDs, issue.ID)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,36 +222,37 @@ Output to stdout by default, or use -o flag for file output.`,
|
|||||||
out = tempFile
|
out = tempFile
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write JSONL (with timestamp-only deduplication for bd-164)
|
// Write JSONL (timestamp-only deduplication DISABLED due to bd-160)
|
||||||
encoder := json.NewEncoder(out)
|
encoder := json.NewEncoder(out)
|
||||||
exportedIDs := make([]string, 0, len(issues))
|
exportedIDs := make([]string, 0, len(issues))
|
||||||
skippedCount := 0
|
skippedCount := 0
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
// Check if this is only a timestamp change (bd-164)
|
// DISABLED: timestamp-only deduplication causes data loss (bd-160)
|
||||||
skip, err := shouldSkipExport(ctx, issue)
|
// The export_hashes table gets out of sync with JSONL after git operations,
|
||||||
if err != nil {
|
// causing exports to skip issues that aren't actually in the file.
|
||||||
// Log warning but continue - don't fail export on hash check errors
|
//
|
||||||
fmt.Fprintf(os.Stderr, "Warning: failed to check if %s should skip: %v\n", issue.ID, err)
|
// skip, err := shouldSkipExport(ctx, issue)
|
||||||
skip = false
|
// if err != nil {
|
||||||
}
|
// fmt.Fprintf(os.Stderr, "Warning: failed to check if %s should skip: %v\n", issue.ID, err)
|
||||||
|
// skip = false
|
||||||
if skip {
|
// }
|
||||||
skippedCount++
|
// if skip {
|
||||||
continue
|
// skippedCount++
|
||||||
}
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
if err := encoder.Encode(issue); err != nil {
|
if err := encoder.Encode(issue); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error encoding issue %s: %v\n", issue.ID, err)
|
fmt.Fprintf(os.Stderr, "Error encoding issue %s: %v\n", issue.ID, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save content hash after successful export (bd-164)
|
// DISABLED: export hash tracking (bd-160)
|
||||||
contentHash, err := computeIssueContentHash(issue)
|
// contentHash, err := computeIssueContentHash(issue)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Warning: failed to compute hash for %s: %v\n", issue.ID, err)
|
// fmt.Fprintf(os.Stderr, "Warning: failed to compute hash for %s: %v\n", issue.ID, err)
|
||||||
} else if err := store.SetExportHash(ctx, issue.ID, contentHash); err != nil {
|
// } else if err := store.SetExportHash(ctx, issue.ID, contentHash); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Warning: failed to save export hash for %s: %v\n", issue.ID, err)
|
// fmt.Fprintf(os.Stderr, "Warning: failed to save export hash for %s: %v\n", issue.ID, err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
exportedIDs = append(exportedIDs, issue.ID)
|
exportedIDs = append(exportedIDs, issue.ID)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user