fix: add NULL hash guards to prevent v5.3.3 regression

Fixed critical bug where CommitObject.walk() didn't guard against NULL parent
hash, causing "Blob metadata not found: 0000...0000" error when calling
getHistory() on fresh databases.

This is a SYSTEMATIC fix, not just a patch:

Infrastructure:
- src/storage/cow/constants.ts: NEW - NULL_HASH constant and utilities
- Prevents hardcoding errors
- Provides isNullHash() for semantic checks

Bug Fixes:
- src/storage/cow/CommitObject.ts: Guard NULL parent in walk()
- src/storage/cow/BlobStorage.ts: Defensive check rejects NULL hash reads
- src/storage/baseStorage.ts: Use NULL_HASH constant (not hardcoded)
- src/brainy.ts: Use NULL_HASH constant (not hardcoded)

Testing:
- tests/integration/initial-commit-null-parent.test.ts: 5 regression tests
- All 17 tests pass (5 new + 12 existing COW tests)
- Zero regressions

This fix addresses the root cause of 4 consecutive bugs (v5.3.0-v5.3.3):
missing defensive programming for sentinel values in COW storage.

Fixes: Workshop team bug report (v5.3.3 regression)
Tests: 17/17 pass (5 new regression + 12 existing COW)
Build: SUCCESSFUL (zero errors)
This commit is contained in:
David Snelling 2025-11-04 15:39:58 -08:00
parent 680322b7f4
commit bb4c0bfb99
6 changed files with 228 additions and 4 deletions

View file

@ -2357,9 +2357,12 @@ export class Brainy<T = any> implements BrainyInterface<T> {
const entityCount = await this.getNounCount()
const relationshipCount = await this.getVerbCount()
// v5.3.4: Import NULL_HASH constant
const { NULL_HASH } = await import('./storage/cow/constants.js')
// Build commit object using builder pattern
const builder = CommitBuilder.create(blobStorage)
.tree('0000000000000000000000000000000000000000000000000000000000000000') // Empty tree hash for now
.tree(NULL_HASH) // Empty tree hash (sentinel value)
.message(options?.message || 'Snapshot commit')
.author(options?.author || 'unknown')
.timestamp(Date.now())