Skip to content

Cross-Program Memory (Feedback Loop)

The core value proposition

Without graffold: each Atlas run starts from zero. Same mistakes, same dead ends, no memory. With graffold: every run builds on every prior run. Cross-program intelligence for free.


How it works

 Atlas Run 1 (crypto)
 push entities + decisions
 ┌─────────────┐
 │ graffold │ ← KG accumulates
 │ (Parquet) │
 └─────────────┘
 query prior knowledge
 Atlas Run 2 (mastitis)

 Run 2 immediately knows:
 • IL-6 = inflammation marker (from crypto, not re-discovered)
 • JAK2 → IL-6 pathway = already characterized
 • Auranofin = KILLED (don't re-propose)
 • CpTrxR = validated lead (redox mechanism proven)

The cycle

flowchart LR
 subgraph Run1["Atlas Run 1 (crypto)"]
 A1[22-agent pipeline] --> E1[entities + decisions]
 end

 subgraph Graffold["graffold-ingest"]
 KG[(Knowledge Graph)]
 end

 subgraph Run2["Atlas Run 2 (mastitis)"]
 PK[prior-knowledge.md] --> A2[22-agent pipeline]
 end

 E1 -->|"graffold-ingest ingest"| KG
 KG -->|"graffold-ingest context"| PK
  1. Atlas Run 1 completes its research program → produces phase-*.md files
  2. graffold-ingest extracts entities, resolves them, publishes to Parquet
  3. Atlas Run 2 starts → calls graffold-ingest context <disease> → gets prior-knowledge.md
  4. Run 2's Pathfinder agent reads prior-knowledge.md and starts with full awareness of what's been tried, what worked, what was killed

What Run 2 receives

The prior-knowledge.md file contains:

Section Content Example
Explored targets All targets from prior runs with status CpTrxR (active), FDFT1 (active), Auranofin (KILLED)
Kill decisions Documented reasons for each kill "Auranofin: gold toxicity, non-oral bioavailability"
Evidence links Verified PMIDs connecting targets to literature PMID 40901734 validates CpTrxR redox mechanism
Selectivity data Host vs parasite orthologue assertions "CpTrxR has no host thioredoxin reductase orthologue"
Mechanism clusters Grouped targets by biological pathway Redox economy: CpTrxR, FDFT1, GSH
Cross-program hits Entities shared across programs IL-6 appears in both crypto and mastitis

Why this matters

Without feedback loop

  • Atlas Run 2 re-discovers IL-6 from scratch (wastes $2-5 in API calls + 10 min)
  • Run 2 might re-propose Auranofin (previously killed for gold toxicity)
  • Run 2 has no awareness that the JAK2→IL-6 pathway was already characterized
  • Every run is an island

With feedback loop

  • Run 2 starts with 301 explored targets already mapped
  • 655 kill decisions prevent wasting time on dead ends
  • 1,087 evidence links provide pre-verified citations
  • Shared mechanisms (inflammation, redox) transfer across disease areas
  • Each subsequent run is faster, cheaper, and higher quality

ROI

Metric Without graffold With graffold
Time to prior-knowledge 0 (no memory) <5 sec query
Redundant target discovery ~30% of targets re-discovered 0%
Killed targets re-proposed Common Never
Cross-program insight Manual (human remembers) Automatic
Cost per additional run Same ($5-15) Decreasing (less re-work)

Try it

# Run the feedback loop demo
python benchmarks/feedback_loop_demo.py

# Or in production:
# After Atlas Run 1 completes:
graffold-ingest ingest ~/atlas/programs/crypto-v11/v1/

# Before Atlas Run 2 starts:
graffold-ingest context mastitis -d ~/atlas/programs/mastitis-v1/v1/
# → writes prior-knowledge.md into the program dir
# → Atlas reads it at startup via Pathfinder

Integration with Atlas CLI

For Atlas developers hooking this into bin/atlas run:

# In atlas/src/atlas/stages/intake.py (before Pathfinder):
import subprocess

def inject_prior_knowledge(program_dir: str, disease: str):
 """Query graffold for cross-run memory before starting Discovery."""
 result = subprocess.run(
 ["graffold-ingest", "context", disease, "-d", program_dir],
 capture_output=True, text=True
 )
 if result.returncode == 0:
 print(f" Prior knowledge injected ({program_dir}/prior-knowledge.md)")
 # Pathfinder will read prior-knowledge.md if it exists

Or via the REST API:

import httpx

async def get_prior_knowledge(disease: str) -> str:
 resp = await httpx.AsyncClient().post(
 "http://localhost:8001/v1/query",
 json={"question": f"What is known about {disease}?", "mode": "global"}
 )
 return resp.json()["answer"]