How to Use Graphify Reflection for Stale Data Detection and Recovery
Graphify reflection generates a .graphify_learning.json side-car that marks lessons as stale when source code fingerprints (SHA-256 hashes) no longer match current files, enabling automated detection of outdated knowledge.
Graphify (Graphify-Labs/graphify) is an open-source knowledge management tool that converts Q&A memory into deterministic lessons. Its reflection engine tracks code changes to identify when cached knowledge becomes stale, allowing agents to ignore outdated advice or trigger regeneration.
How Graphify Reflection Detects Stale Data
The reflection process in graphify/reflect.py transforms memory documents into a structured learning overlay. It fingerprints source files to detect when lesson content no longer reflects the current implementation.
The Reflection Pipeline
The reflection pipeline executes six distinct steps to generate lessons and detect staleness:
- Collect memory docs –
load_memory_docsparses every*.mdfile containing front-matter written bygraphify save-result(lines 33-57) ingraphify/reflect.py. - Aggregate lessons –
aggregate_lessonsscores each source node with time-decayed weights, grouping them into preferred, tentative, and contested buckets while recording provenance events (lines 64-78). - Render the lessons file –
render_lessons_mdproduces a stable markdown document atgraphify-out/reflections/LESSONS.md(lines 90-110). - Build the learning side-car –
build_learning_overlayresolves each node to a canonical ID and adds acode_fingerprint(SHA-256 hash of the node's source file) via_content_hash(lines 672-679). - Write the side-car –
write_learning_sidecarwrites.graphify_learning.jsonbeside the graph in a deterministic, sorted format (lines 331-338). - Detect staleness – The
_is_stalefunction (lines 687-699) compares stored fingerprints against current file hashes.
The Learning Side-Car Structure
The .graphify_learning.json file contains metadata for each node referenced in the lessons:
code_fingerprint: SHA-256 hash of the source file content at the time of reflectionstale: Boolean flag indicating whether the implementation has changedsource_file: Path to the source file (resolved via_resolve_source_path)generated_at: Timestamp of lesson creation
This side-car is generated by build_learning_overlay and written atomically to prevent corruption during concurrent access.
The Staleness Check Algorithm
When load_learning_overlay loads the side-car, it invokes _is_stale to validate each entry:
_resolve_source_path(lines 668-682) handles absolute paths, layout-specific roots, and the optional.graphify_rootmarker to locate the current source file.- The function recomputes the SHA-256 hash of the current file and compares it with the stored
code_fingerprint. - If the file is missing, the hash differs, or no fingerprint was recorded, the entry is marked stale (lines 687-699).
Detecting Stale Data Programmatically
You can consume the reflection artifacts in Python to build staleness-aware workflows.
Loading the Side-Car with load_learning_overlay
Import load_learning_overlay from graphify.reflect to access the staleness metadata:
from pathlib import Path
from graphify.reflect import load_learning_overlay
graph_path = Path("graphify-out/graph.json")
learning = load_learning_overlay(graph_path)
# Returns a dict: node_id → entry dict
print(f"Loaded {len(learning)} lesson entries")
Each entry contains the stale boolean, code_fingerprint, and source_file path.
Filtering Stale Entries
Filter the overlay to identify outdated lessons that require attention:
# Filter for stale entries only
stale_nodes = {
nid: entry for nid, entry in learning.items()
if entry.get("stale")
}
print(f"Found {len(stale_nodes)} stale lessons:")
for nid, entry in stale_nodes.items():
print(f"- {entry['label']} (id={nid}) – last updated {entry['generated_at']}")
This pattern allows agents to exclude stale guidance from prompt context or flag them for review.
Refreshing Stale Lessons
When stale data is detected, you can regenerate the lessons using either the CLI or the Python API.
CLI Workflow
Run reflection from the command line to regenerate the lessons file and side-car:
graphify reflect --memory graphify-out/memory \
--out graphify-out/reflections/LESSONS.md \
--graph graphify-out/graph.json \
--if-stale # skips work if output is already fresh
The --if-stale flag optimizes performance by checking modification times before recomputing. The command reads memory docs, aggregates lessons, writes LESSONS.md, and produces .graphify_learning.json beside the graph.
Programmatic Refresh with lessons_fresh
Use the Python API to conditionally refresh only when necessary:
from pathlib import Path
from graphify.reflect import reflect, lessons_fresh
memory_dir = Path("graphify-out/memory")
out_path = Path("graphify-out/reflections/LESSONS.md")
graph_path = Path("graphify-out/graph.json")
# Re-run only if source files changed
if not lessons_fresh(out_path, memory_dir, graph_path=graph_path):
reflect(memory_dir, out_path, graph_path=graph_path)
print("Lessons refreshed – stale data updated.")
else:
print("Lessons are up-to-date.")
The lessons_fresh function checks file modification times, while the side-car provides content-hash verification for cryptographic certainty.
Summary
- Graphify reflection produces a deterministic
LESSONS.mdartifact and a.graphify_learning.jsonside-car containing SHA-256 fingerprints for every source node. - Stale detection occurs in
_is_stale(lines 687-699 ofgraphify/reflect.py), which compares stored fingerprints against current file hashes using_resolve_source_path. - Programmatic access via
load_learning_overlayreturns a dictionary where thestaleboolean flag indicates outdated entries. - Conditional regeneration uses
lessons_freshto avoid unnecessary computation, while the--if-staleCLI flag provides similar optimization for shell workflows.
Frequently Asked Questions
What does "stale data" mean in Graphify?
In Graphify, stale data refers to a lesson whose associated source code has been modified or deleted after the lesson was generated. The reflection engine stores a SHA-256 fingerprint of each source file; when load_learning_overlay detects a hash mismatch or missing file via _is_stale, it marks the entry as stale to prevent agents from relying on outdated guidance.
How does Graphify track code changes for staleness?
Graphify tracks changes through content hashing rather than timestamps. During reflection, build_learning_overlay computes a code_fingerprint (SHA-256 hash) for each node's source file (lines 672-679 in graphify/reflect.py). When loading the overlay, _is_stale recomputes the hash and compares it to the stored fingerprint, marking the entry stale if they differ or if the file is missing.
Can I skip reflection if lessons are already fresh?
Yes. Use the --if-stale flag in the CLI to skip processing when outputs are current, or call lessons_fresh(out_path, memory_dir, graph_path=graph_path) in Python to check modification times before invoking reflect. This prevents unnecessary I/O when source files and memory documents haven't changed since the last run.
Where is the stale data metadata stored?
The staleness metadata is stored in .graphify_learning.json, a JSON side-car file written beside your graph file (e.g., graphify-out/graph.json). This file is generated by write_learning_sidecar (lines 331-338) and contains the code_fingerprint, stale boolean, and source_file path for each lesson entry.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →