fix(node-ui): read SWM/VM attribution across all sub-graph partitions (B2)#1055
Merged
Merged
Conversation
… (B2) The SWM Attribution legend (useSwmAttributions) and the VM anchor decorations (useVerifiedMemoryAnchors) query every sub-graph's _shared_memory_meta partition via a STRSTARTS(?g, <cgUri>) filter, but also sent contextGraphId in the /api/query body. With contextGraphId and no view, the query engine constrains GRAPH ?g to a CG-direct allow-list that excludes the per-sub-graph _shared_memory_meta partitions, so the filter could never reach them: the legend showed 1 agent when 5 had attributed in a one-agent-per-sub-graph deployment. Fix: omit contextGraphId from both fetch bodies. The SPARQL's own STRSTARTS filter already scopes to the CG and reaches all partitions (the same raw-query pattern the integration's swm-scan runbook uses). Per-entity detail-view attribution (B2a) is unaffected: it reads the entity's own prov:wasAttributedTo, a separate data-graph path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codex review (PR #1055): with contextGraphId removed (B2), scoping rests entirely on the SPARQL STRSTARTS prefix. The bare "did:dkg:context-graph:<cg>" prefix is not exact and would also match a sibling CG (e.g. cg-10, cg-1-foo), merging its _shared_memory_meta rows into the legend/anchors. Add a trailing slash so the prefix is exact: every partition graph is did:dkg:context-graph:<cg>/[<sg>/]_shared_memory_meta, so "<cgUri>/" matches all of this CG's partitions and excludes siblings. Applied to buildAttributionsQuery and buildAnchorsQuery; added query-shape guards asserting the exact prefix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fix scoping Codex flagged that, since CG ids may contain "/", a path-extending child CG `<cg>/<x>` is URI-identical to a real sub-graph `<sg>=<x>` and would still match the exact "<cgUri>/" prefix. Disambiguating needs the sub-graph registry (the deferred server-side SWM routing, A2/A4). Document this as a known limitation in both query builders and the rationale for preferring the raw-prefix read over a client-built registry allow-list (which would re-drop partitions whose _meta registration is missing — a condition seen live). No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ining cgId Codex: the deferred-promise mock recovered the cgId via `[^"/]+`, which truncates a canonical `<wallet>/project` id at the first slash, so the Code7 test could pass while routing under the wrong key. Parse the full quoted STRSTARTS prefix up to the trailing `/"` instead, and switch the test's ids to slash-containing (`acme/alpha`, `acme/beta`) so it actually exercises that path — the old regex would now route them under `acme` and fail the test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Open
6 tasks
6 tasks
branarakic
added a commit
that referenced
this pull request
Jun 8, 2026
Brings in #1055 (node-ui SWM/VM attribution) + the rc.17 CI fixes (file-serving route, handle-request, hermes tests) so the #1019 PR diffs cleanly against the current base. Sole conflict was publish-jsonld.test.ts: both branches independently repointed the 3 confirmed-publish VM-read fixtures at the per-KA _verified_memory graph — resolved to the base's canonical read-both queries (root OR _verified_memory/, staging-excluded); my 4 async-lift it.skip deferrals are preserved.
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.
Summary
DKG-NODE-ISSUES-FOR-RC17): the node-UI SWM Attribution legend under-counted contributing agents in one-agent-per-sub-graph deployments — it showed 1 agent when 5 had attributed (live on-disk: Curator 1, Literature 11, Trials 4, Mechanism 4, Synthesis 1).useSwmAttributionsalready scopes its query to the context graph (CG) inside the SPARQL viaFILTER(STRSTARTS(STR(?g), "did:dkg:context-graph:<cg>") && CONTAINS(STR(?g), "_shared_memory_meta")), so it intends to read every sub-graph's…/<sg>/_shared_memory_metapartition. But it also sentcontextGraphIdin the/api/querybody. WithcontextGraphIdset and noview, the query engine constrains theGRAPH ?gvariable to a CG-direct allow-list (dkg-query-engine.tsgraph-variable allow-list) that excludes per-sub-graph_shared_memory_metapartitions, so theSTRSTARTSfilter can never bind them. Only the CG-direct partition's agents were counted.contextGraphIdfrom the POST body. The SPARQL's ownSTRSTARTSfilter already scopes to the CG and reaches all partitions — the same raw-query pattern the integration'sswm-scanrunbook uses. Note:includeContextGraphPartitions:truewould not fix this (per A4 the partition-discovery allow-list skips_shared_memory_metaentirely); omittingcontextGraphIdis the proven path.useVerifiedMemoryAnchors(VM on-chain anchor decorations) — sameSTRSTARTS + _shared_memory_metaquery whose own docstring says it enumerates "every sub-graph's_shared_memory_meta", silently scoped to the CG-direct partition by the samecontextGraphId. Directly relevant to this VM-focused base branch.prov:wasAttributedTo(data-graph scoped, a separate path) and is unchanged.useAssertionLifecycleEventsis intentionally left alone — it targets a hardcoded CG-levelGRAPH <…/_meta>(no sub-graph partitions), wherecontextGraphIdis legitimately required.Related
DKG-NODE-ISSUES-FOR-RC17.md(medical-research showcase feedback).4935dafc1("feat(node-ui): dkg-v9 subgraphs PoC") addedcontextGraphIdto the attribution fetch — harmless before sub-graphs existed (all SWM attribution lived in CG-direct graphs), but it began dropping per-sub-graph partitions once data moved into them.view/includeContextGraphPartitionsrouting for sub-graph SWM. This PR is the client-side one-line workaround that makes the UI correct today.Files changed
packages/node-ui/src/ui/hooks/useSwmAttributions.tscontextGraphIdfrom the/api/querybody so the attribution query reaches every sub-graph_shared_memory_meta; comment explaining why it must not be re-added.packages/node-ui/src/ui/hooks/useVerifiedMemoryAnchors.tspackages/node-ui/test/use-swm-attributions.test.tscontextGraphId; update the stale-on-switch mock to route by the cgId embedded in the SPARQL (body no longer carries it).packages/node-ui/test/use-verified-memory-anchors.test.tscontextGraphId.Test plan
vitest run test/use-swm-attributions.test.ts test/use-verified-memory-anchors.test.ts→ 4 passed (3 SWM incl. the new B2 guard + the existing Code5/Code7 cases; 1 VM anchors).pnpm --filter @origintrail-official/dkg-node-ui test): 0 test-assertion failures, +2 passing vs the clean base. The branch has ~10 pre-existing flaky file-level failures in stateful suites (db/notifications/messenger-stores/chat-memory/ etc.) — reproduced on the clean base with these changes stashed, and the failing set shifts run-to-run; none relate to SWM/VM attribution.pnpm --filter @origintrail-official/dkg-node-ui build(tsc) → clean.contextGraphIdthe daemon returns 1 agent (~16s); without it, 5 agents / 2,084 rows (~0.23s). The legend now renders all five contributing agents.Known limitations (accepted)
STRSTARTS(?g, "<cgUri>/")prefix, which correctly excludes siblings likecg-10/cg-1-foo. However,validateContextGraphIdpermits/inside CG ids (convention<addr>/<name>), so a path-extending child CG<cg>/<x>produces a graph URI byte-identical to a real sub-graph<sg>=<x>of<cg>. Only the sub-graph registry can disambiguate the two; doing so authoritatively is the deferred server-side sub-graph SWM routing (A2/A4)./api/sub-graph/list) was considered and rejected: it re-introduces a B2-class under-count whenever a present sub-graph's_metaregistration is missing — a condition this showcase hit live (deriveCuratorDidFromCgIdand the runbook's "missing sub-graph registration step" exist for exactly that). The raw-prefix read surfaces whatever partitions physically exist, which is more robust under those gaps.e2466174a). Maintainer-accepted.discoverKnownChildContextGraphUrisfrom Enable subGraphName scoping with view-based routing in the query engine #184/Support subgraph-scoped view routing #1037; once it lands, these hooks can drop the raw-prefix read.