Add missing reconnectMu.RLock() protection to storage methods that were
vulnerable to the same race condition fixed in GH#607. The FreshnessChecker
can trigger reconnect() which closes s.db while queries are in flight,
causing "database is closed" errors during daemon export operations.
Protected methods:
- labels.go: GetLabelsForIssues (GetLabels intentionally unprotected - called from GetIssue which holds lock)
- comments.go: GetIssueComments, GetCommentsForIssues
- dependencies.go: GetDependencyCounts, GetDependencyRecords, GetAllDependencyRecords, GetDependencyTree, loadDependencyGraph
- config.go: SetConfig, GetConfig, GetAllConfig, DeleteConfig, SetMetadata, GetMetadata
- dirty.go: MarkIssueDirty, GetDirtyIssues, GetDirtyIssueHash, GetDirtyIssueCount
- events.go: GetEvents, GetStatistics, GetMoleculeProgress
- hash.go: All hash methods
- hash_ids.go: GetNextChildID, ensureChildCounterUpdated (getNextChildNumber unprotected - called internally)
Internal helpers called from already-locked contexts intentionally omit
RLock to avoid deadlock (Go's RWMutex doesn't support recursive locking).
Fixes: bd-vx7fp
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
## Problem
Export deduplication feature broke when JSONL and export_hashes diverged
(e.g., after git pull/reset). This caused exports to skip issues that
weren't actually in the file, leading to silent data loss.
## Solution
1. JSONL integrity validation before every export
- Store JSONL file hash after export
- Validate hash before export, clear export_hashes if mismatch
- Automatically recovers from git operations changing JSONL
2. Clear export_hashes on all imports
- Prevents stale hashes from causing future export failures
- Import operations invalidate export_hashes state
3. Add Storage interface methods:
- GetJSONLFileHash/SetJSONLFileHash for integrity tracking
- ClearAllExportHashes for recovery
## Tests Added
- TestJSONLIntegrityValidation: Unit tests for validation logic
- TestImportClearsExportHashes: Verifies imports clear hashes
- TestExportIntegrityAfterJSONLTruncation: Simulates git reset (would have caught bd-160)
- TestExportIntegrityAfterJSONLDeletion: Tests recovery from file deletion
- TestMultipleExportsStayConsistent: Tests repeated export integrity
## Follow-up
Created bd-179 epic for remaining integration test gaps (multi-repo sync,
daemon auto-sync, corruption recovery tests).
Closes bd-160
- Remove duplicate computeIssueContentHash from sqlite/hash.go
- Remove FileUsed() from internal/config/config.go
- Remove verifyIssueOpen() test helper from git_sync_test.go
- Remove unimplemented SummarizeTier2 and all tier2 infrastructure from haiku.go
Removes ~120 LOC of dead code identified by deadcode analyzer.
Amp-Thread-ID: https://ampcode.com/threads/T-5f150c35-8d67-4dae-bb92-a7b5887d649d
Co-authored-by: Amp <amp@ampcode.com>