Skip to content

fix(memory): graph-edge refresh for reused Notion chunks across doc-root versions #3385

Closed

Description

@coderabbitai

Summary

When a Notion chunk is reused across document versions (same chunk_id, derived from sha256(source_kind || source_id || seq || content)), the parent_summary_id / parent_id backlinks in mem_tree_chunks / mem_tree_summaries are written only when the column IS NULL (see seal_explicit_children in src/openhuman/memory_tree/tree/bucket_seal.rs). This means reused chunks remain permanently linked to the first/older doc-root and never get re-pointed when a newer version seals.

Impact

  • Affected consumer: collect_tree_graph / graph_export in src/openhuman/memory/read_rpc.rs (~line 1369), which maps parent_summary_id → GraphNode.parent_id for the memory-graph UI edge display.
  • Not affected: retrieval/ranking path (drill_down) — it descends via child_ids and selects the latest doc-root using max(version_ms), so recall and ranking are unaffected.
  • Net severity: cosmetic graph-edge misdirection only — the UI edge arrow points to the older doc-root revision for reused chunks; zero impact on recall or ranking.

Desired fix

Update seal_explicit_children backlink logic to re-point parent_summary_id / parent_id for children belonging to the same tree/document, rather than only writing when IS NULL. Care should be taken to ensure the UPDATE is scoped to the correct tree_id to avoid cross-tree mutations.

References

Requested by @sanil-23.

Activity

  1. sanil-23 commented on Jun 5, 2026

    @sanil-23
    Collaborator

    Closing as completed — the requested fix is already on main.

    Requested change: re-point parent_summary_id for reused chunks instead of only writing when IS NULL, so a chunk shared across doc-root versions backlinks to the latest version rather than being stranded on the first.

    Current state in seal_explicit_children (src/openhuman/memory_tree/tree/bucket_seal.rs:1339-1353): the level-0 (chunk) branch now does an unconditional re-point — no IS NULL guard:

    // Unconditional re-point (no IS NULL guard): a byte-identical body chunk
    // reused across doc versions upserts to the SAME row (content-addressed id),
    // so its single parent_summary_id must follow the newest version. ...
    UPDATE mem_tree_chunks SET parent_summary_id = ?1 WHERE id = ?2

    Doc-subtrees seal newest-last, so last-write-wins leaves the backlink on the latest doc-root — which is what retrieval surfaces (max(version_ms) per doc_id). The sibling summary branch (level > 0) keeps the AND parent_id IS NULL guard, which is correct: summaries carry version_ms and each version seals a new summary row (id not reused), so its parent_id always starts NULL — only content-addressed chunks are reused across versions, and those are now handled.

    Net: the cosmetic graph-edge misdirection this issue described (collect_tree_graph / graph_export pointing a reused chunk's edge at the older doc-root) no longer occurs. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions