The class-killer for the lost-main.dkann incident (ADR-004 §7). A provider can declare a derived-index blob FAMILY (a set of members that are load-bearing together, e.g. vector-base = main.dkann + main.slotmap + main.slotrev). Once declared: - deleteBinaryBlob / removeRawPrefix REFUSE to remove a declared member, throwing the new ProtectedArtifactError — an in-process GC / sweeper is now INCAPABLE of deleting a load-bearing index file (COLD != DEAD). Intentional retirement is an explicit unregisterDerivedFamily(name) first. - The declaration persists to _system/derived-artifacts.json, so protection survives a reopen; clear() resets it with the rest of the derived footprint. - checkDerivedFamiliesPresent() names any member missing on open (the catch for an EXTERNAL deleter that bypasses the in-process refusal) → rebuild from canonical. - Transients (*.tmp.*, *.rebuild-tmp, *.rotate-tmp) are never protected; a namespace family protects a growing prefix (seg-*). New StorageAdapter surface (optional): registerDerivedFamily / unregisterDerivedFamily / listDerivedFamilies + DerivedFamilyDeclaration; new exported errors ProtectedArtifactError / DerivedArtifactMissingError. Enforcement is inert until a provider declares a family (no regression). Cor declares its 6 families + does the atomic set-swap in 3.0.15 (M2); brainy builds the contract now. 8 tests. |
||
|---|---|---|
| .. | ||
| blob-save-durability.test.ts | ||
| blobStorage.compression-policy.test.ts | ||
| blobStorage.test.ts | ||
| clear-native-footprint.test.ts | ||
| getNouns-totalCount.test.ts | ||
| getVerbs-totalCount.test.ts | ||
| registered-blob-contract.test.ts | ||
| sharding-new-installation-log.test.ts | ||
| sharding.test.ts | ||
| stats-count-accuracy.test.ts | ||
| storage-path-resolution.test.ts | ||
| verb-cursor-pagination.test.ts | ||
| vfs-mkdir-bug.test.ts | ||