# How the Memory Loop Persists Q&A Results for Re‑Ingestion in code‑review‑graph

> Learn how the memory loop in code-review-graph persists Q&A results using timestamped Markdown files. Re-ingest prior knowledge across sessions for improved code reviews.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: internals
- Published: 2026-08-06

---

**The memory loop persists every question/answer pair as a timestamped Markdown file with YAML front‑matter inside a repository‑specific directory, enabling agents to retrieve and re‑ingest prior knowledge across separate MCP sessions.**

The **memory loop** in **code‑review‑graph** is a lightweight feedback mechanism that creates a persistent, file‑based knowledge base. According to the source code in `tirth8205/code-review-graph`, this system captures analysis results as structured Markdown documents that downstream processes can query, update, and feed back into the graph enrichment pipeline for incremental learning.

## Core Persistence Functions

The persistence layer is implemented in [`code_review_graph/memory.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/memory.py) through three primary utilities that handle the complete lifecycle of stored knowledge.

### Saving Results with `save_result()`

The `save_result()` function (lines 14‑74) transforms ephemeral Q&A interactions into durable artifacts. It constructs a filename from the question text, appends a timestamp, and writes a Markdown document containing:

- **YAML front‑matter** with fields for `type`, `timestamp`, and an optional `nodes` list (explicitly capped at 20 items to prevent bloating)
- An **ATX‑style heading** (`# `) that stores the original question followed by the answer body

Files are stored under `<repo>/.code-review-graph/memory/` by default, though callers may specify a custom directory. The function returns the absolute path to the created file, allowing immediate verification of persistence.

### Reading Stored Memories with `list_memories()`

Retrieval is handled by `list_memories()` (lines 77‑115), which performs a scoped directory scan for `*.md` files. For each file discovered, the function:

1. Parses the YAML front‑matter to extract metadata
2. Extracts the first `# ` heading as the canonical question text

3. Returns a structured dictionary containing `path`, `question`, `type`, `timestamp`, and other metadata

This metadata‑first approach allows agents to filter memories efficiently before reading full file contents, optimizing the re‑ingestion workflow when feeding historical Q&A back into the analysis graph.

### Cleaning Up with `clear_memories()`

The `clear_memories()` utility (lines 121‑141) provides targeted cleanup by deleting only Markdown files within the memory directory. It returns a count of removed files, enabling audit logging and preventing accidental deletion of source code or other repository artifacts.

## Storage Format and File Structure

The memory system uses a strict file‑naming convention and directory structure to ensure compatibility across sessions:

```text
<repo_root>/
└── .code-review-graph/
    └── memory/
        ├── how-does-auth-work-2024-01-15-143022.md
        └── explain-memory-loop-2024-01-15-145511.md

```

Each Markdown file follows this pattern:

```markdown
---
type: query
timestamp: "2024-01-15T14:30:22"
nodes:
  - code_review_graph.memory.save_result
  - code_review_graph.graph
---

# How does the memory loop work?

It stores Q&A as markdown for later ingestion.

```

The combination of machine‑readable front‑matter and human‑readable Markdown ensures the memory loop serves both automated re‑ingestion pipelines and manual debugging workflows.

## Practical Implementation

Agents interact with the memory layer through the Python API exposed in [`code_review_graph/memory.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/memory.py):

```python
from pathlib import Path
from code_review_graph.memory import save_result, list_memories, clear_memories

# Persist a query result for future re‑ingestion

repo_root = Path("/path/to/repo")
save_result(
    question="How does the memory loop work?",
    answer="It stores Q&A as markdown for later ingestion.",
    nodes=["code_review_graph.memory.save_result", "code_review_graph.graph"],
    result_type="query",
    repo_root=repo_root,  # Uses .code-review-graph/memory by default

)

# Retrieve all stored Q&A entries for graph enrichment

for meta in list_memories(repo_root=repo_root):
    print(meta["question"], "→", meta["type"], "at", meta["timestamp"])

# Remove memories when they are no longer needed

deleted = clear_memories(repo_root=repo_root)
print(f"Removed {deleted} markdown memory files")

```

The test suite in [`tests/test_memory.py`](https://github.com/tirth8205/code-review-graph/blob/main/tests/test_memory.py) validates this persistence cycle, ensuring that saved memories remain readable and deletable across different execution contexts.

## Summary

- **The memory loop** serializes Q&A interactions as timestamped Markdown files in a dedicated subdirectory (`.code-review-graph/memory/`).
- **`save_result()`** caps related nodes at 20 items and writes YAML front‑matter alongside the answer content.
- **`list_memories()`** enables efficient metadata scanning without loading full file contents, supporting scalable re‑ingestion.
- **`clear_memories()`** provides safe cleanup limited to Markdown artifacts, protecting repository source files.
- This file‑based architecture allows incremental learning across separate MCP sessions without requiring external databases.

## Frequently Asked Questions

### What directory does the memory loop use for storage?

By default, the system creates a hidden directory at `<repo_root>/.code-review-graph/memory/`. Callers can override this by passing a custom `repo_root` argument to `save_result()`, `list_memories()`, or `clear_memories()`.

### How does the memory loop prevent filename collisions?

The `save_result()` function generates filenames by sanitizing the question text and appending a timestamp, ensuring unique files even when identical questions are asked repeatedly. This convention is implemented in lines 14‑74 of [`code_review_graph/memory.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/memory.py).

### Is there a limit to how many nodes can be associated with a memory?

Yes, the implementation explicitly caps the `nodes` list at 20 items in the YAML front‑matter. This prevents memory files from growing excessively large while preserving the most relevant code paths for context.

### How do you clear old memories without affecting the repository?

Use the `clear_memories()` function, which targets only `*.md` files within the memory directory. It leaves all other repository files untouched and returns the number of files deleted, as verified by [`tests/test_memory.py`](https://github.com/tirth8205/code-review-graph/blob/main/tests/test_memory.py).