Repository Planning Graph (RPG)
The Repository Planning Graph (RPG) is the structural intelligence layer that makes a Forge agent swarm coherent. It indexes the structural and semantic graph of a codebase — files, classes, functions, imports, data flows, features — and lets agents ask questions, plan changes, and check for conflicts against a live, queryable model of the repo. Combined with MemoryLayer’s memory store, it gives the swarm a shared, identity-aware view of both what was decided (memory) and what the code is (graph).
Scitrera Forge is the product that ties this together: dozens of sandboxed agents (planners, coders, reviewers, retrievers) coordinating in parallel, with RPG as the source of truth for the codebase and MemoryLayer as the source of truth for everything else. The two together are what make autonomous, multi-agent programming on large repos tractable.
Why RPG?
Agents that work over code without a planning graph have to keep rediscovering the same structural facts every time the context resets:
- “Where is
authenticateUsercalled from?” - “Which files would change if I rename this class?”
- “Two agents are working in parallel — do their tasks conflict?”
- “What’s the actual data flow between
auth/anddb/?”
RPG persists these answers as a graph in MemoryLayer. Nodes are Memory entities, edges are Associations — which means everything you already get from MemoryLayer (vector search, knowledge graph traversal, decay, recall) is available against the code graph, side by side with conversation memory.
Concretely, RPG gives you:
- A canonical graph of files, directories, classes, functions, methods, modules, packages, interfaces, components, variables, and imports
- Overlay contexts (
rpg-task-*,rpg-intent-*) so each in-flight task or intent has its own staging graph that can be diffed and merged into the canonical view - Conflict detection between concurrent tasks at the file and symbol level
- LLM enrichment that adds one-line descriptions, feature groupings, and data-flow edges on top of the structural graph
- Maintenance operations (validate, cleanup, statistics, recompute counts) so the graph stays healthy as the repo evolves
- Microservice Intelligence RPG w/ LLM enrichment enables identifying data flow across languages and service boundaries, enabling handling complex, scalable, microservice architecture monorepos.
Architecture at a Glance
┌─────────────────────────────────────────────────────────────┐│ Forge / IDE / Agent ─────► /v1/rpg/sync ──► RpgService ││ (emits nodes+edges) ││ ││ MemoryLayer storage ││ ┌──────────────────────────┐ ││ │ Memory (rpg_* subtypes) │ ││ │ Association (edges) │ ││ └──────────────────────────┘ ││ ││ Agent ─────► /v1/rpg/{subgraph,search,merged-subgraph, ││ conflicts,...} ──► reasons + plans │└─────────────────────────────────────────────────────────────┘RPG runs as an in-process component of MemoryLayer when Forge is deployed:
- Registers FastAPI routes under
/v1/rpg/*. - Reuses the core
StorageBackend— no new database is required. - Honors the same authentication and authorization model as the rest of MemoryLayer (
memories:read/memories:writescopes). - Cooperates with Aether-issued grants for OBO delegation across Forge’s agent swarm so every graph mutation is attributable to a specific agent acting on behalf of a specific user.
What Gets Indexed
| Node type | Represents |
|---|---|
rpg_directory | A folder in the repo |
rpg_file | A source file |
rpg_module / rpg_package | Language-level module / package boundary |
rpg_class / rpg_interface | Class / interface declaration |
rpg_function / rpg_method | Top-level function / class method |
rpg_variable | Module-level variable or constant |
rpg_import | Import statement target |
rpg_component | Higher-level feature component (added by enrichment) |
Edges use MemoryLayer’s existing relationship ontology — contains, imports, invokes, inherits_from, data_flows_to, etc.
API Surface (under /v1/rpg)
All routes are workspace-scoped via the authenticated principal.
Sync
POST /v1/rpg/syncBulk-upsert a snapshot of nodes and edges. Supports full and incremental syncs and accepts an optional context_id so overlays can be written to their own partition (rpg, rpg-task-<id>, rpg-intent-<id>). Canonical full syncs auto-schedule LLM enrichment.
Query
| Endpoint | Purpose |
|---|---|
GET /v1/rpg/subgraph | Neighborhood query rooted at a file path or node id (up to 10 hops) |
GET /v1/rpg/search | Free-text search across node names, descriptions, and paths |
GET /v1/rpg/nodes | Enumerate nodes, optionally filtered by node_type |
GET /v1/rpg/status | Encoding status for a workspace / context |
GET /v1/rpg/merged-subgraph | Base + overlay merged view (e.g. canonical + a task’s intent) |
Overlays
| Endpoint | Purpose |
|---|---|
GET /v1/rpg/overlays | List active rpg-task-* / rpg-intent-* contexts |
DELETE /v1/rpg/overlays/{context_id} | Drop an entire overlay |
DELETE /v1/rpg/nodes | Bulk delete by node id |
DELETE /v1/rpg/edges | Bulk delete by association id |
Conflict detection
| Endpoint | Purpose |
|---|---|
GET /v1/rpg/conflicts?task_id=... | File-level conflicts between this task’s intent overlay and other active intents |
GET /v1/rpg/conflicts/symbols?task_id_a=...&task_id_b=... | Symbol-level conflicts between two task overlays (high = same symbol, medium = same file) |
This is what makes RPG load-bearing for multi-agent workflows: before letting two agents merge in parallel, the orchestrator can call /conflicts/symbols and decide whether they touch the same code.
Enrichment & maintenance
| Endpoint | Purpose |
|---|---|
POST /v1/rpg/enrich | Run LLM enrichment phases (features, descriptions, data_flows) — sync or async via the task service |
POST /v1/rpg/maintenance/{op} | validate, cleanup, statistics, cleanup_intents, or recompute_counts |
Example: Subgraph Around a File
curl "$MEMORYLAYER_URL/v1/rpg/subgraph?path=src/auth/login.ts&depth=2" \ -H "Authorization: Bearer $API_KEY"Returns the node for src/auth/login.ts, its declared classes / functions, what it imports, and one more hop — enough to brief an agent before it edits the file.
Example: Conflict Check Between Two Task Overlays
curl "$MEMORYLAYER_URL/v1/rpg/conflicts/symbols?task_id_a=task-42&task_id_b=task-43" \ -H "Authorization: Bearer $API_KEY"Compares the rpg-task-42 and rpg-task-43 overlays and returns every symbol modified by both, with a severity field (high for exact symbol match, medium for same file).
Example: Enrich the Canonical Graph
curl -X POST "$MEMORYLAYER_URL/v1/rpg/enrich" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "context_id": "rpg", "phases": ["descriptions", "data_flows"], "async": true }'Schedules a background task that uses the configured LLM service to add one-line class/interface descriptions and detected data-flow edges to the canonical graph. Trigger this after a large sync, or wire it into your CI.
How It Fits With the Rest of MemoryLayer
- RPG nodes are first-class memories — they show up in
/v1/memories/recallif you don’t filter them out, which is occasionally useful (an agent asking “where is auth handled?” gets back both code-graph nodes and prior decision memories). - The
include_rpgflag on/v1/graphand/v1/knowledgebaselets workspace-wide graph analysis pull RPG nodes in alongside knowledge memories without a separate call. - Overlays are normal context partitions, so the existing context-scoped queries work over them without special-casing.
- The Memory subtypes used by RPG (
rpg_file,rpg_class, …) are contributed via the standardOntologyContributorPluginextension point — they are not hard-coded into the OSS server.
Why It Belongs in the Same Server
Putting the code graph in the same store as conversation memory unlocks queries that neither alone can answer:
- “Last time we touched this file, we hit a deadlock — recall the fix” — joins RPG file nodes with episodic problem/solution memories.
- “Surface the architectural decisions affecting
src/auth/” — joins RPG path neighborhood withdecisionsubtype memories. - “Find every file touched by a task that contradicted the documented intent” — joins RPG task overlays with
contradictsassociations from the conversation graph.
This is the longer-term reason RPG was built as a MemoryLayer plugin rather than a standalone service: graph traversal across both kinds of knowledge is a single query, not a federated mess.
Availability
RPG is a component of Scitrera Forge and is not distributed independently. Scitrera Forge is currently restricted to organizations on the approved access list — the system is, candidly, too powerful for general public release at this stage. The open-source MemoryLayer server includes the integration hooks (include_rpg flag on /v1/graph and /v1/knowledgebase, the OntologyContributorPlugin extension point used by RPG subtypes) so an OSS deployment can interoperate cleanly with a Forge-enabled environment, but the RPG service itself does not ship as an oss/ package.
If you believe your use case warrants access — particularly if you’re running large multi-repo agent workflows, internal developer platforms, or anything that benefits from autonomous code understanding at scale — reach out via scitrera.ai.
Related Pages
- scitrera.ai — Scitrera Forge access requests and contact
- Knowledge Graph — the underlying typed-association model RPG builds on
- Architecture — where the RPG integration hooks sit in the system diagram