LearnNewsExamplesServices
Frontmatter
id10058
titleMemory Core Graph: Add PR Nodes and RESOLVED_BY Edges for Ticket→PR Mapping
stateClosed
labels
enhancementaiarchitectureneeds-re-triage
assignees[]
createdAtApr 18, 2026, 12:48 AM
updatedAt3:19 PM
githubUrlhttps://github.com/neomjs/neo/issues/10058
authortobiu
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 6, 2026, 7:44 PM

Memory Core Graph: Add PR Nodes and RESOLVED_BY Edges for Ticket→PR Mapping

Closed v13.0.0/archive-v13-0-0-chunk-4 enhancementaiarchitectureneeds-re-triage
tobiu
tobiu commented on Apr 18, 2026, 12:48 AM

Intent / The Why

The Memory Core's Native Edge Graph (GraphService.mjs) maps structural and episodic knowledge: class hierarchies (IMPLEMENTS, EXTENDS), focus priorities (FOCUS_ON), system tenets (SYSTEM_TENET), and cross-framework analogies (ANALOGOUS_TO). However, it has no representation of the Problem→Solution arc between GitHub Issues and their resolving Pull Requests.

This matters because:

  1. Deterministic traversal beats fuzzy search. An agent asking "what resolved issue #10051?" should get PR #10053 via a single graph hop (RESOLVED_BY edge), not by running a vector similarity search and hoping the PR body mentions the ticket number.
  2. The Q&A reward signal. The ticket body describes the problem (intent, requirements, constraints). The PR body describes the solution (implementation, trade-offs, review feedback). Linking them structurally creates a traversable reward signal that agents can learn from: "this is how problems like X get solved."
  3. Context Frontier enrichment. When get_context_frontier primes an agent session, PR nodes with RESOLVED_BY edges would surface recent solution patterns alongside ongoing work items — giving agents implementation precedent, not just problem descriptions.

Why the Graph (not the KB)?

The KB (ChromaDB) is for semantic similarity — "find me things that sound like X." The graph is for structural certainty — "this PR resolved this issue, period." The relationship is factual, not probabilistic. It belongs in the graph.

Scope of Work

1. PR Node Type

Add support for type: 'pull-request' nodes in GraphService:

GraphService.upsertNode({
    id         : 'pr-10053',
    type       : 'pull-request',
    name       : 'chore(ai): ticket-intake acceptance protocol (#10051)',
    description: 'Merged PR resolving issue #10051',
    properties : {
        number  : 10053,
        state   : 'MERGED',
        mergedAt: '2026-04-17T...',
        author  : 'tobiu'
    }
});

2. RESOLVED_BY Edge Type

Add RESOLVED_BY as a recognized relationship:

GraphService.linkNodes('issue-10051', 'pr-10053', 'RESOLVED_BY', 5.0, {
    context_source: 'pr-sync',
    extracted_from: 'Resolves #10051'
});

Ensure RESOLVED_BY is excluded from decay in decayGlobalTopology() (same treatment as IMPLEMENTS, EXTENDS, SYSTEM_TENET) — these are factual relationships that should never decay.

3. Ingestion Mechanism

The extraction should parse Resolves #N / Closes #N patterns from PR body frontmatter/markdown. Two options for ingestion point:

  • Option A: Dream Pipeline stage — A new stage in the REM cycle that reads resources/content/pulls/*.md, extracts ticket references, and upserts nodes + edges. This runs asynchronously and is self-healing.
  • Option B: PullRequestSyncer hook — Inject graph updates directly into the GitHub Workflow server's PullRequestSyncer after it writes markdown files. Tighter coupling but real-time.

Recommendation: Option A (Dream Pipeline) aligns better with the existing architecture where the graph is populated by periodic background processes, not by real-time syncer hooks.

Key Files

File Action
ai/mcp/server/memory-core/services/GraphService.mjs [MODIFY] Add RESOLVED_BY to decay exclusion list
ai/mcp/server/memory-core/services/SessionService.mjs (or new DreamStage) [MODIFY/NEW] PR→Issue extraction logic
Graph seed data [MODIFY] Optional: backfill existing merged PRs

Reference

  • GraphService.linkNodes() — the API for creating edges
  • GraphService.decayGlobalTopology() line 272 — WHERE type NOT IN ('IMPLEMENTS', 'EXTENDS', 'SYSTEM_TENET') needs 'RESOLVED_BY' added
  • resources/content/pulls/pr-10019.md — example PR markdown showing Resolves #10021 in body

Acceptance Criteria

  • PR nodes (type: 'pull-request') can be upserted into the graph
  • RESOLVED_BY edges link issue nodes to PR nodes
  • RESOLVED_BY edges survive decay cycles
  • query_hybrid_graph(nodeId='issue-10051') returns the resolving PR as a neighbor
  • get_context_frontier surfaces recent PR resolutions alongside active epics

Origin Session ID: 144326a4-c1e8-4eee-80e4-b984f3c79ddc

tobiu added the enhancement label on Apr 18, 2026, 12:48 AM
tobiu added the ai label on Apr 18, 2026, 12:48 AM
tobiu added the architecture label on Apr 18, 2026, 12:48 AM