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

@ -303,7 +303,9 @@ export abstract class BaseStorage extends BaseStorageAdapter {
const mainRef = await this.refManager.getRef('main')
if (!mainRef) {
// Create initial commit with empty tree
const emptyTreeHash = '0000000000000000000000000000000000000000000000000000000000000000'
// v5.3.4: Use NULL_HASH constant instead of hardcoded string
const { NULL_HASH } = await import('./cow/constants.js')
const emptyTreeHash = NULL_HASH
// Import CommitBuilder
const { CommitBuilder } = await import('./cow/CommitObject.js')