Skip to content

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-2024 and pentest-beta-2024 are 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.