fix: critical clear() data persistence regression (v5.10.4)
Workshop team reported that brain.clear() doesn't fully delete persistent storage. After calling clear() and creating a new Brainy instance, all data was restored from storage. This is a CRITICAL data integrity bug. Root causes (3 bugs fixed): 1. **FileSystemStorage deleting wrong directory**: Data stored in branches/main/entities/ but clear() was only deleting old pre-v5.4.0 structure (nouns/, verbs/, metadata/) 2. **COW reinitialization after clear()**: Setting cowEnabled=false on old instance doesn't affect new instances. Fixed with persistent marker file. 3. **Metadata index cache not cleared**: find() with type filters returned stale data after clear(). Fixed by recreating MetadataIndexManager. Changes: - FileSystemStorage: Clear branches/ directory (where data actually lives) - All storage adapters: Add checkClearMarker()/createClearMarker() methods - BaseStorage: Check for cow-disabled marker before initializing COW - Brainy: Recreate metadataIndex after clear() to flush cached data - Tests: Comprehensive regression suite (8 tests) to prevent recurrence Fixes Workshop bug report: /media/dpsifr/storage/home/Projects/workshop/BRAINY_V5_10_2_CLEAR_BUG.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
53420f6c9a
commit
aba15638dc
11 changed files with 613 additions and 17 deletions
|
|
@ -1001,20 +1001,13 @@ export class FileSystemStorage extends BaseStorage {
|
|||
}
|
||||
}
|
||||
|
||||
// Remove all files in the nouns directory
|
||||
await removeDirectoryContents(this.nounsDir)
|
||||
|
||||
// Remove all files in the verbs directory
|
||||
await removeDirectoryContents(this.verbsDir)
|
||||
|
||||
// Remove all files in the metadata directory
|
||||
await removeDirectoryContents(this.metadataDir)
|
||||
|
||||
// Remove all files in the noun metadata directory
|
||||
await removeDirectoryContents(this.nounMetadataDir)
|
||||
|
||||
// Remove all files in the verb metadata directory
|
||||
await removeDirectoryContents(this.verbMetadataDir)
|
||||
// v5.10.4: Clear the entire branches/ directory (branch-based storage)
|
||||
// Bug fix: Data is stored in branches/main/entities/, not just entities/
|
||||
// The branch-based structure was introduced for COW support
|
||||
const branchesDir = path.join(this.rootDir, 'branches')
|
||||
if (await this.directoryExists(branchesDir)) {
|
||||
await removeDirectoryContents(branchesDir)
|
||||
}
|
||||
|
||||
// Remove all files in both system directories
|
||||
await removeDirectoryContents(this.systemDir)
|
||||
|
|
@ -1037,6 +1030,12 @@ export class FileSystemStorage extends BaseStorage {
|
|||
this.blobStorage = undefined
|
||||
this.commitLog = undefined
|
||||
this.cowEnabled = false
|
||||
|
||||
// v5.10.4: Create persistent marker file (CRITICAL FIX)
|
||||
// Bug: cowEnabled = false only affects current instance, not future instances
|
||||
// Fix: Create marker file that persists across instance restarts
|
||||
// When new instance calls initializeCOW(), it checks for this marker
|
||||
await this.createClearMarker()
|
||||
}
|
||||
|
||||
// Clear the statistics cache
|
||||
|
|
@ -1075,6 +1074,49 @@ export class FileSystemStorage extends BaseStorage {
|
|||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if COW has been explicitly disabled via clear()
|
||||
* v5.10.4: Fixes bug where clear() doesn't persist across instance restarts
|
||||
* @returns true if marker file exists, false otherwise
|
||||
* @protected
|
||||
*/
|
||||
protected async checkClearMarker(): Promise<boolean> {
|
||||
// Check if fs module is available
|
||||
if (!fs || !fs.promises) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
const markerPath = path.join(this.systemDir, 'cow-disabled')
|
||||
await fs.promises.access(markerPath, fs.constants.F_OK)
|
||||
return true // Marker exists
|
||||
} catch (error) {
|
||||
return false // Marker doesn't exist (ENOENT) or can't be accessed
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create marker indicating COW has been explicitly disabled
|
||||
* v5.10.4: Called by clear() to prevent COW reinitialization on new instances
|
||||
* @protected
|
||||
*/
|
||||
protected async createClearMarker(): Promise<void> {
|
||||
// Check if fs module is available
|
||||
if (!fs || !fs.promises) {
|
||||
console.warn('FileSystemStorage.createClearMarker: fs module not available, skipping marker creation')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const markerPath = path.join(this.systemDir, 'cow-disabled')
|
||||
// Create empty marker file
|
||||
await fs.promises.writeFile(markerPath, '', 'utf8')
|
||||
} catch (error) {
|
||||
console.error('FileSystemStorage.createClearMarker: Failed to create marker file', error)
|
||||
// Don't throw - marker creation failure shouldn't break clear()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about storage usage and capacity
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue