fix(namespace): noun-record updates preserve legacy inline HNSW adjacency — the placeholder-adjacency write stamped out pre-codec records' stored connections (crash-window unreachability); codec-era records were never at risk (empty field is the blob marker); pin covers the legacy shape
This commit is contained in:
parent
7a28a94639
commit
4679c89458
2 changed files with 68 additions and 2 deletions
|
|
@ -77,8 +77,27 @@ export class SaveNounOperation implements Operation {
|
|||
? null
|
||||
: await this.storage.getNoun(this.noun.id)
|
||||
|
||||
// Save new noun
|
||||
await this.storage.saveNoun(this.noun)
|
||||
// PRESERVE stored graph state on updates. Callers stage this op with
|
||||
// placeholder adjacency ({connections: empty, level: 0}) because the
|
||||
// vector index owns those values and persists them at flush. Codec-era
|
||||
// records (2.4.0+) carry an empty connections field by design (adjacency
|
||||
// lives in a separate compressed blob — the placeholder is harmless), but
|
||||
// LEGACY pre-codec records store adjacency INLINE: writing the
|
||||
// placeholder over one stamped out its stored connections, leaving a
|
||||
// crash window (until the next flush) where a reload found the node
|
||||
// unreachable. Stale adjacency in that window is tolerable — HNSW
|
||||
// self-corrects at the reindex flush; EMPTY adjacency is silent recall
|
||||
// loss. The read above is already paid for rollback; preservation is free.
|
||||
const toSave: HNSWNoun =
|
||||
previousNoun && this.noun.connections.size === 0
|
||||
? {
|
||||
...this.noun,
|
||||
connections: previousNoun.connections || this.noun.connections,
|
||||
level: previousNoun.level ?? this.noun.level
|
||||
}
|
||||
: this.noun
|
||||
|
||||
await this.storage.saveNoun(toSave)
|
||||
|
||||
// Return rollback action
|
||||
return async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue