Session Persistence¶
CRP supports cross-session knowledge persistence via the Contextual Knowledge Fabric (CKF). Facts survive session restarts, enabling multi-day workflows where each session picks up where the last left off.
Memory Tiers¶
CRP uses three memory tiers:
| Tier | Name | Lifetime | Storage |
|---|---|---|---|
| 1 | Hot (Envelope) | Current window | In-memory |
| 2 | Warm (Session) | Current session | In-memory |
| 3 | Cold (CKF) | Persistent | SQLite + vectors + graph |
Facts flow downward: Hot → Warm → Cold on session close. Facts flow upward: Cold → Warm → Hot on relevance match.
How It Works¶
sequenceDiagram
participant Session1
participant CKF
participant Session2
Note over Session1: Day 1 - Recon
Session1->>Session1: dispatch() → extract facts
Session1->>Session1: More dispatches, more facts
Session1->>CKF: close() → flush to cold storage
Note over CKF: Facts persisted to disk
Note over Session2: Day 2 - Analysis
Session2->>CKF: init() → cold state available
Session2->>Session2: dispatch("Analyze findings")
Note over Session2: CKF retrieves relevant Day 1 facts
Session2->>Session2: Envelope includes Day 1 knowledge
Example: Multi-Day Penetration Test¶
import crp
# Day 1: Reconnaissance
session = crp.init(
provider="ollama",
model="qwen3-4b",
app_id="pentest-acme-2024" # Persistent identity
)
session.dispatch(task="Enumerate subdomains for acme.com")
session.dispatch(task="Scan discovered hosts for open ports")
session.dispatch(task="Identify running services and versions")
# Save to cold storage
session.close()
# Facts flushed to ~/.crp/storage/pentest-acme-2024/
# Day 2: Exploitation
session = crp.init(
provider="ollama",
model="qwen3-4b",
app_id="pentest-acme-2024" # Same app_id
)
# Day 1's recon facts are automatically available
result = session.dispatch(
task="Based on the discovered services, identify potential vulnerabilities"
)
# The model knows about the subdomains, ports, and services from Day 1
Cold Storage Structure¶
CKF stores data at ~/.crp/storage/{app_id}/:
~/.crp/storage/pentest-acme-2024/
├── facts.db # SQLite: all facts with metadata
├── vectors.idx # Vector index for semantic retrieval
├── graph.db # Fact relationship graph
└── communities.json # Leiden community clusters
CKF Retrieval Modes¶
When a new session starts, CKF retrieves relevant facts using four methods:
| Mode | How It Works | Best For |
|---|---|---|
| Graph Walk | Traverse fact relationships | Connected concepts |
| Pattern Query | Regex/keyword matching | Specific entities |
| Semantic Fallback | Vector similarity search | Conceptual matches |
| Community Summaries | Leiden cluster summaries | Broad topic recall |
CRP tries them in order and combines results.
Exporting State¶
For portability, export the session state as an encrypted snapshot:
# Export
snapshot = session.export_state()
# snapshot is an encrypted binary blob with BLAKE3 checksum
# Import on another machine
session = crp.init(provider="ollama", model="qwen3-4b")
session.import_state(snapshot)
The persisted state header includes:
| Field | Purpose |
|---|---|
schema_version |
State format version |
protocol_version |
CRP version that created it |
created_at |
Timestamp |
checksum |
BLAKE3 integrity hash |
Session Isolation¶
Sessions are isolated by app_id:
pentest-acme-2024andpentest-beta-2024are completely separate- No fact leakage between app_ids
- Each app_id has its own cold storage directory
Best Practices¶
Use meaningful app_ids
Use descriptive app_ids like project-name-phase rather than random strings.
This makes it easy to find and manage persistent storage.
Close sessions properly
Always call session.close() to flush facts to cold storage. If the
process crashes, warm state facts are lost.
Storage growth
Cold storage grows with each session. For long-running projects, monitor the storage directory size and prune old app_ids if needed.