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:
David Snelling 2025-11-17 10:44:35 -08:00
parent 53420f6c9a
commit aba15638dc
11 changed files with 613 additions and 17 deletions

View file

@ -300,6 +300,15 @@ export abstract class BaseStorage extends BaseStorageAdapter {
branch?: string
enableCompression?: boolean
}): Promise<void> {
// v5.10.4: Check for persistent marker file (CRITICAL FIX)
// Bug: Setting cowEnabled = false on OLD instance doesn't affect NEW instances
// Fix: Check storage for persistent marker created by clear()
// If marker exists, COW was explicitly disabled and should NOT reinitialize
const markerExists = await this.checkClearMarker()
if (markerExists) {
return // COW was disabled by clear() - don't recreate _cow/ directory
}
// v5.6.1: If COW was explicitly disabled (e.g., via clear()), don't reinitialize
// This prevents automatic recreation of COW data after clear() operations
if (this.cowEnabled === false) {
@ -1704,6 +1713,23 @@ export abstract class BaseStorage extends BaseStorageAdapter {
*/
public abstract clear(): Promise<void>
/**
* Check if COW has been explicitly disabled via clear()
* v5.10.4: Fixes bug where clear() doesn't persist across instance restarts
* Each adapter checks for a marker file/object (e.g., "_system/cow-disabled")
* @returns true if COW was disabled by clear(), false otherwise
* @protected
*/
protected abstract checkClearMarker(): Promise<boolean>
/**
* Create marker indicating COW has been explicitly disabled
* v5.10.4: Called by clear() to prevent COW reinitialization on new instances
* Each adapter creates a marker file/object (e.g., "_system/cow-disabled")
* @protected
*/
protected abstract createClearMarker(): Promise<void>
/**
* Get information about storage usage and capacity
* This method should be implemented by each specific adapter