Skip to content

feat(graph): add a labeled relation graph with a query surface - #161

Merged
drewstone merged 1 commit into
mainfrom
feat/relation-graph
Aug 21, 2026
Merged

feat(graph): add a labeled relation graph with a query surface#161
drewstone merged 1 commit into
mainfrom
feat/relation-graph

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

Why

buildKnowledgeGraph is hardcoded to page links and keys edges by source->target, so two predicates between one pair collapse into one edge with merged reasons. KnowledgeRelation has an arbitrary predicate, but nothing builds a graph from it and nothing queries one. A consumer with labeled provenance (runs, claims, models; branched-from, supersedes, cites-evidence) had to hand-roll the builder and every query.

What

  • src/relation-graph.ts: buildKnowledgeRelationGraph({ nodes?, relations }) builds a KnowledgeRelationGraph with one edge per (sourceId, targetId, predicate) in first-seen order. A repeated triple is accepted only when its weight and metadata are byte-identical in canonical JSON; any other repeat, an endpoint outside declared nodes, a duplicate node id, an empty id/kind/predicate, a non-finite weight, or non-JSON metadata is refused with a typed KnowledgeRelationGraphError (code). Without nodes, the graph carries edges only.
  • neighbors(graph, id, { predicate?, direction }), walk(graph, id, { predicate?, direction, maxDepth? }) (breadth-first, visited set, cycle-safe; ancestors = out over branched-from, descendants = in), isReachable(graph, from, to, { predicate?, direction }). An unknown node or malformed query is refused, never an empty answer.
  • KnowledgeRelationSchema (hoisted out of KnowledgeBaseCandidateSchema, one definition), KnowledgeRelationNodeSchema, KnowledgeRelationGraphSchema, each with an explicit metadata: z.record(z.string(), z.unknown()).optional() so a persisted graph round-trips.
  • knowledgePageRelations(pages) emits the labeled page relations (wikilink, citation, shared-source, contradicts), one per triple with occurrence weights. buildKnowledgeGraph now collapses that list into its weighted edges (one source of truth); contradicts stays out of the collapsed projection and the implicit shared-source pass stays out of the relation graph.
  • Exported from the entrypoint; README and docs/architecture.md lines; CHANGELOG 8.1.0; api-surface.json regenerated (20 added exports, additive → minor).

Proof (local, macOS, Node 24.11.1)

  • pnpm run typecheck: pass (src + contracts).
  • pnpm run lint: 227 files, no fixes.
  • pnpm test: 672 passed, 16 skipped, 48 failed — all 48 in tests/kb-improvement/* (6 files), which throw exact knowledge candidate workflows require Linux directory descriptors on macOS; unrelated to this change. Focused: src/relation-graph.test.ts 11/11, src/graph.test.ts 5/5, src/citation-storage.test.ts 4/4, tests/core.test.ts + src/search.test.ts 24/24.
  • Golden test: buildKnowledgeGraph(pages) over a fixture covering double-resolved links, origin-qualified and malformed citations, ambiguous duplicate ids, self links, shared sources, and contradicts is JSON.stringify-identical to the output recorded from the pre-refactor implementation (key order, edge order, weights, degrees).
  • pnpm run build: 35 files. pnpm api:surface: 926 exports across 6 entry points. pnpm run check:version-bump: 20 export changes needing a minor bump, paid for by 8.0.10 -> 8.1.0.
  • git merge-tree --write-tree origin/main HEAD: clean.

Closes #124

Add buildKnowledgeRelationGraph, neighbors, walk, and isReachable over
KnowledgeRelation edges keyed by (sourceId, targetId, predicate), with
KnowledgeRelationSchema, KnowledgeRelationNodeSchema, and
KnowledgeRelationGraphSchema so a persisted graph round-trips its metadata.
Add knowledgePageRelations and derive buildKnowledgeGraph from it; the
collapsed page graph bytes do not change.

Closes #124
@drewstone
drewstone requested a review from tangletools August 21, 2026 00:08

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Auto-approved drewstone PR — 9b6870b3

This PR was opened by the trusted drewstone account.

This approval is provisional and was applied by the local stand-in because the pr-reviewer webhook host is unreachable (2026-08-21). CI on this head is fully green. The full PR reviewer audit re-runs via the resweep when the service returns and will publish findings if it detects issues.

@drewstone
drewstone merged commit a03c4e7 into main Aug 21, 2026
2 checks passed
@drewstone
drewstone deleted the feat/relation-graph branch August 21, 2026 01:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provenance graph: no builder or query surface for labeled multi-edge relations (KnowledgeRelation)

2 participants