{{ message }}
feat(graph,mcp): annotate_nodes — write external metadata back onto graph nodes#162
Open
avfirsov wants to merge 1 commit into
Open
feat(graph,mcp): annotate_nodes — write external metadata back onto graph nodes#162avfirsov wants to merge 1 commit into
avfirsov wants to merge 1 commit into
Conversation
…nodes Add a sanctioned, additive write-back path so a downstream tool (an LLM, an analysis pass, an editor extension) can enrich existing graph nodes with its own metadata — without re-indexing and without racing the sharded in-memory store. - graph.Store.MergeNodeMeta(id, kv) (changed, found): the only sanctioned way for a Store holder to mutate Node.Meta. Additive + idempotent (deep-equal delta via metaDelta), shard-locked, and never touches structural fields (id/kind/name/path/lines). Implemented for both the in-memory and SQLite backends and covered by a shared store-conformance case so they behave identically. - mcp annotate_nodes tool (also served at POST /v1/tools/annotate_nodes through the shared registry): merges a free-form per-node `meta` map under a caller-chosen `namespace` (default "ext") so annotations can never shadow indexer-owned keys, and optionally adds idempotent semantically_related edges between node pairs. Tests: pure metaDelta unit, in-memory + SQLite conformance, and MCP handler round-trip / idempotency / namespace / edge / bad-input plus a registration guard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XcQY8fFFyDQidwVC8dKHWh
Owner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What
Adds a sanctioned, additive write-back path for external metadata so a downstream tool — an LLM enrichment pass, an analysis stage, an editor extension — can attach its own metadata to existing graph nodes without re-indexing and without racing the sharded in-memory store.
Today there is no safe way for a caller holding a
graph.Store(rather than a concrete*Graph) to mutateNode.Meta: the shard lock the in-memory backend takes is private, so reaching intoGetNode(id).Metadirectly races the sharded map and panics on a live daemon. This PR closes that gap.How
graph.Store.MergeNodeMeta(id, kv) (changed, found)— the only sanctionedNode.Metamutation path for aStoreholder. Additive and idempotent (deep-equal delta via the puremetaDeltahelper), taken under the node's shard write lock, and it never touches structural fields (id / kind / name / path / lines). Implemented for both the in-memory and SQLite backends and covered by a shared store-conformance case so the two behave identically.annotate_nodesMCP tool (also served atPOST /v1/tools/annotate_nodesthrough the shared registry — no separate HTTP code): merges a free-form per-nodemetamap under a caller-chosennamespace(defaultext). Every key is stored as<namespace>_<key>, so an annotation can never shadow an indexer-owned Meta key. Optionally adds idempotentsemantically_relatededges between node pairs. Returns{annotated, unchanged, not_found, edges_added}.The merge is deliberately scoped: never deletes keys, never mutates structural data, non-fatal per item (an unknown id is recorded in
not_found, the batch continues).Tests
metaDeltaunit (delta/idempotency/nil-handling).MergeNodeMeta): additive merge, deep-equal idempotency, found semantics for an unknown id, lazyMetainit, structural fields untouched.namespaceprefixing (incl. no double-prefix),semantically_relatededge add + dedup, default score, bad input, and a registration guard.All green;
go build ./...,go vet, andgofmtclean on the changed files.Notes / scope
🤖 Generated with Claude Code