Python (rag_plusplus.slice)
1. [Overview](#1-overview) 2. [Architecture](#2-architecture) 3. [Core Concepts](#3-core-concepts) 4. [Graph Kernel Service (Rust)](#4-graph-kernel-service-rust) 5. [RAG++ Slice Client (Python)](#5-rag-slice-client-python) 6. [Slice-Conditioned Retrieval](#6-slice-conditioned-retrieval) 7. [Provenance Chain](#7-provenance-chain) 8. [Production Hardening](#8-production-hardening) 9. [API Reference](#9-api-reference) 10. [Deployment](#10-deployment) 11. [Testing](#11-testing) 12. [Migration Guide](#12-migration-guide
Full Public Reader
``# Graph Kernel + RAG++ Integration
Technical Implementation Documentation
Version: 1.1.0
Last Updated: 2026-01-01
Status: Production Ready
> See Also: [Production Invariants](./PRODUCTION_INVARIANTS.md) for non-negotiable rules.
---
Table of Contents
1. [Overview](#1-overview)
2. [Architecture](#2-architecture)
3. [Core Concepts](#3-core-concepts)
4. [Graph Kernel Service (Rust)](#4-graph-kernel-service-rust)
5. [RAG++ Slice Client (Python)](#5-rag-slice-client-python)
6. [Slice-Conditioned Retrieval](#6-slice-conditioned-retrieval)
7. [Provenance Chain](#7-provenance-chain)
8. [Production Hardening](#8-production-hardening)
9. [API Reference](#9-api-reference)
10. [Deployment](#10-deployment)
11. [Testing](#11-testing)
12. [Migration Guide](#12-migration-guide)
---
1. Overview
1.1 Purpose
This integration makes `cc-graph-kernel` the sole authority for determining what context is allowed to influence meaning in RAG++ retrieval. The core principle is:
> Nothing downstream is allowed to read "raw graph neighborhoods" directly. Everything must be mediated by `SliceExport` from the Graph Kernel.
1.2 Key Benefits
| Benefit | Description |
|---|---|
| Determinism | Same anchor + policy → same slice_id → byte-for-byte reproducible results |
| Provenance | Full chain of custody: query → slice → results → semantic artifacts |
| Admissibility Gating | Only slice-scoped results can promote to semantic artifacts |
| Replay Capability | Any retrieval can be replayed by citing (slice_id, query_hash, policy_hash) |
1.3 Two Retrieval Modes
┌─────────────────────────────────────────────────────────────────┐
│ RAG++ Retrieval │
├─────────────────────────────┬───────────────────────────────────┤
│ Slice-RAG │ Global-RAG │
│ (Admissibility-Gated) │ (Explicit Exception) │
├─────────────────────────────┼───────────────────────────────────┤
│ • Anchor-first │ • No anchor required │
│ • Slice-scoped candidates │ • Whole-fabric search │
│ • is_admissible = true │ • is_admissible = false │
│ • Can trigger promotions │ • Cannot trigger promotions │
│ • Full provenance chain │ • Provenance (but marked global) │
└─────────────────────────────┴───────────────────────────────────┘---
2. Architecture
2.1 System Overview
┌──────────────────────────────────────────────────────────────────────────┐
│ Client Application │
│ (trajectory-search, Orbit, Claude Code) │
└─────────────────────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ RAG++ Service (Python) │
│ Port 8000 │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ SliceClient │ │ MemoryRetriever │ │ DualPlaneRetriever │ │
│ │ │ │ │ │ │ │
│ │ • get_slice() │ │ • search_slice()│ │ • raw_turns │ │
│ │ • get_batch() │ │ • search_global()│ │ • atoms/proposals │ │
│ └────────┬────────┘ └────────┬────────┘ └────────────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌─────────────────────┐ │
│ │ │ RetrievalProvenance │ │
│ │ │ • query_id │ │
│ │ │ • slice_id │ │
│ │ │ • is_admissible │ │
│ │ └─────────────────────┘ │
└───────────┼──────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Graph Kernel Service (Rust) │
│ Port 8001 │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ ContextSlicer │ │ PolicyRegistry │ │ PostgresGraphStore │ │
│ │ │ │ │ │ │ │
│ │ • slice() │ │ • register() │ │ • get_turn() │ │
│ │ • fingerprint │ │ • resolve() │ │ • get_parents() │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Supabase (PostgreSQL) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ memory_turns │ │ semantic_atoms │ │ semantic_proposals │ │
│ │ │ │ │ │ │ │
│ │ • id (UUID) │ │ • source_turn_ids│ │ • source_atoms │ │
│ │ • embedding │ │ • source_slice_id│ │ • source_slice_id │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘2.2 Data Flow
1. Client sends search request with anchor_turn_id
│
▼
2. RAG++ SliceClient calls Graph Kernel: POST /api/slice
│
▼
3. Graph Kernel builds SliceExport:
• Expands from anchor using policy
• Computes deterministic fingerprint
• Returns ordered turn_ids + edges
│
▼
4. RAG++ MemoryRetriever.search_slice():
• Filters candidates to admissible_turn_ids
• Executes vector search
• Attaches provenance chain
│
▼
5. Results returned with full provenance:
• query_id, slice_id, anchor_turn_id
• is_admissible = true
• Can be used for semantic promotions---
3. Core Concepts
3.1 SliceExport
The `SliceExport` is the fundamental unit of context admissibility:
// Rust (cc-graph-kernel)
pub struct SliceExport {
pub slice_id: SliceFingerprint, // Deterministic hash
pub anchor_turn_id: TurnId, // Anchor turn
pub turns: Vec<TurnSnapshot>, // Ordered turns
pub edges: Vec<Edge>, // Ordered edges
pub policy_id: String, // e.g., "slice_policy_v1"
pub policy_params_hash: String, // xxHash64 of policy JSON
pub schema_version: String, // Graph Kernel schema version
}# Python (rag_plusplus.slice)
@dataclass
class SliceExport:
slice_id: str
anchor_turn_id: str
turn_ids: List[str]
edge_count: int
policy_id: str
policy_params_hash: str
schema_version: str
def is_admissible(self, turn_id: str) -> bool:
"""Check if a turn is in this slice."""
return turn_id in self._turn_id_set3.2 PolicyRef
A stable reference to a registered slice policy:
@dataclass(frozen=True)
class PolicyRef:
policy_id: str # "slice_policy_v1"
params_hash: str # xxHash64 of canonical JSONDeterminism Guarantee: Same `PolicyRef` + same anchor + same graph state = identical `slice_id`.
3.3 RetrievalProvenance
Complete chain of custody for search results:
@dataclass
class RetrievalProvenance:
query_id: str # Unique per request
retrieval_mode: Literal["slice", "global"]
query_text: str
retrieved_turn_ids: List[str]
timestamp: str
elapsed_ms: float
# Slice-specific (None for global)
slice_info: Optional[SliceInfo]
# For replay verification
query_embedding_hash: Optional[str]
result_hash: Optional[str]
@property
def is_admissible(self) -> bool:
"""Only slice-mode results are admissible."""
return self.retrieval_mode == "slice" and self.slice_info is not None---
4. Graph Kernel Service (Rust)
4.1 Module Structure
core/cc-graph-kernel/
├── Cargo.toml # Added 'service' feature
├── Dockerfile.service # Production container
└── src/
├── lib.rs # Exports service module
├── bin/
│ └── graph_kernel_service.rs # Service binary
└── service/
├── mod.rs # Module entry point
├── state.rs # PolicyRegistry, ServiceState
└── routes.rs # Axum handlers4.2 PolicyRegistry
The `PolicyRegistry` manages immutable policies with stable hashes:
pub struct PolicyRegistry {
policies: BTreeMap<PolicyRef, SlicePolicyV1>,
registry_fingerprint: String,
}
impl PolicyRegistry {
/// Register a policy, returning its reference.
pub fn register(&mut self, policy: SlicePolicyV1) -> PolicyRef {
let policy_ref = PolicyRef::from_policy(&policy);
if !self.policies.contains_key(&policy_ref) {
self.policies.insert(policy_ref.clone(), policy);
self.update_fingerprint();
}
policy_ref
}
/// Resolve a reference to the actual policy.
pub fn resolve(&self, policy_ref: &PolicyRef) -> Option<&SlicePolicyV1> {
self.policies.get(policy_ref)
}
}4.3 API Endpoints
| Method | Path | Description |
|---|---|---|
| `POST` | `/api/slice` | Construct a slice around an anchor |
| `POST` | `/api/slice/batch` | Batch slice construction |
| `GET` | `/api/policies` | List registered policies |
| `POST` | `/api/policies` | Register a new policy |
| `GET` | `/health` | Service health check |
POST /api/slice
Request:
{
"anchor_turn_id": "550e8400-e29b-41d4-a716-446655440000",
"policy_ref": {
"policy_id": "slice_policy_v1",
"params_hash": "abc123..."
}
}Response:
{
"slice": {
"slice_id": "slice_fingerprint_hash",
"anchor_turn_id": "550e8400-...",
"turn_ids": ["turn1", "turn2", "turn3"],
"edge_count": 2,
"policy_id": "slice_policy_v1",
"policy_params_hash": "abc123...",
"schema_version": "1.0.0"
},
"policy_ref": {
"policy_id": "slice_policy_v1",
"params_hash": "abc123..."
}
}4.4 Running the Service
# Development
cd core/cc-graph-kernel
DATABASE_URL=postgresql://... cargo run --bin graph_kernel_service --features service
# Production
docker build -f Dockerfile.service -t graph-kernel .
docker run -p 8001:8001 -e DATABASE_URL=... graph-kernel---
5. RAG++ Slice Client (Python)
5.1 Module Structure
rag_plusplus/slice/
├── __init__.py # Exports SliceClient, SliceExport, PolicyRef, AnchorResolver
├── client.py # SliceClient for Graph Kernel communication
└── anchor.py # AnchorResolver for query-to-anchor mapping5.2 SliceClient
from rag_plusplus.slice import SliceClient, PolicyRef
client = SliceClient(
base_url="http://localhost:8001", # Or GRAPH_KERNEL_URL env var
timeout=30.0,
)
# Get a slice for an anchor
slice_export = await client.get_slice(
anchor_turn_id="550e8400-e29b-41d4-a716-446655440000",
policy_ref=PolicyRef("slice_policy_v1", "abc123"), # Optional
)
# Batch slicing for atlas operations
slices = await client.get_slice_batch(
anchor_turn_ids=["turn1", "turn2", "turn3"],
policy_ref=policy_ref,
)
# Register a custom policy
custom_policy_ref = await client.register_policy(
max_nodes=128,
max_radius=5,
include_siblings=True,
)5.3 AnchorResolver
The `AnchorResolver` maps query context to anchor turns:
from rag_plusplus.slice import AnchorResolver
resolver = AnchorResolver(supabase_client)
# Explicit anchor
anchor = await resolver.resolve_explicit("turn_uuid")
# From session (latest turn)
anchor = await resolver.resolve_from_session("session_id")
# Semantic match (find best anchor for query)
anchor = await resolver.resolve_from_query(
query="authentication flow",
embedding=query_embedding,
)
# Temporal (most recent turns)
anchors = await resolver.resolve_temporal(limit=5, project_id="proj_123")5.4 AutoAnchorResolver
Automatic resolution with fallback strategies:
from rag_plusplus.slice.anchor import AutoAnchorResolver
auto_resolver = AutoAnchorResolver(resolver)
# Tries in order: explicit → session → semantic → temporal
anchor = await auto_resolver.resolve(
turn_id=None, # No explicit anchor
session_id="sess_1", # Try session first
query="auth flow", # Fall back to semantic
embedding=embedding,
)---
6. Slice-Conditioned Retrieval
6.1 SliceScopedQuery
Extends `SearchQuery` with slice context:
from rag_plusplus.retrieval import SliceScopedQuery
# Create from SliceExport
query = SliceScopedQuery.from_slice_export(
text="authentication flow",
slice_export=slice_export,
limit=10,
)
# Check admissibility
assert query.is_admissible("turn_001") == True
assert query.is_admissible("turn_999") == False # Not in slice
# Filter candidates
admissible = query.filter_admissible(["turn_001", "turn_999"])
# Returns: ["turn_001"]6.2 MemoryRetriever Extensions
Two new methods added to `MemoryRetriever`:
search_slice()
from rag_plusplus.retrieval import MemoryRetriever
retriever = MemoryRetriever()
# Slice-conditioned search
results = retriever.search_slice(
query="authentication flow",
slice_export=slice_export,
limit=10,
)
# Results are SliceScopedResults
assert results.provenance.is_admissible == True
assert results.provenance.slice_id == slice_export.slice_id
for result in results:
print(f"Turn: {result.turn_id}, Similarity: {result.similarity}")search_global()
# Global search (explicit exception mode)
results = retriever.search_global(
query="authentication flow",
limit=10,
)
# Results are GlobalResults
assert results.provenance.is_admissible == False
assert results.provenance.slice_id is None6.3 Two-Stage Retrieval Process
┌─────────────────────────────────────────────────────────────────┐
│ search_slice() Process │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Stage 1: Admissibility Filtering │
│ ───────────────────────────────── │
│ • Get slice.turn_ids from SliceExport │
│ • Create admissible_turn_ids set │
│ • Only these IDs can appear in results │
│ │
│ Stage 2: Vector Search │
│ ────────────────────── │
│ • Generate query embedding │
│ • If |admissible| < 100: Use IN clause (efficient) │
│ • If |admissible| >= 100: Over-fetch + client filter │
│ • Rank by similarity within admissible set │
│ │
│ Stage 3: Provenance Construction │
│ ──────────────────────────────── │
│ • Attach slice_id, anchor_turn_id, policy_ref │
│ • Hash query embedding for replay verification │
│ • Set is_admissible = true │
│ │
└─────────────────────────────────────────────────────────────────┘---
7. Provenance Chain
7.1 Complete Provenance Structure
provenance = RetrievalProvenance(
query_id="uuid-v4",
retrieval_mode="slice",
query_text="authentication flow",
retrieved_turn_ids=["turn_001", "turn_002"],
timestamp="2026-01-01T12:00:00Z",
elapsed_ms=42.5,
slice_info=SliceInfo(
slice_id="slice_abc123",
anchor_turn_id="turn_anchor",
turn_count=50,
edge_count=49,
policy_ref=PolicyRef("slice_policy_v1", "hash123"),
schema_version="1.0.0",
),
query_embedding_hash="sha256_prefix",
result_hash="sha256_prefix",
filters_applied={"min_salience": 0.5},
limit_requested=10,
limit_returned=2,
)7.2 Using Provenance for Gating
def can_promote_to_atom(result: SearchResult, provenance: RetrievalProvenance) -> bool:
"""Only admissible results can be promoted to semantic atoms."""
if not provenance.is_admissible:
return False
# Verify result is in the slice
if str(result.turn_id) not in provenance.retrieved_turn_ids:
return False
return True
# Usage
if can_promote_to_atom(result, results.provenance):
atom = create_semantic_atom(result, source_slice_id=provenance.slice_id)7.3 Replay Verification
def verify_replay(
original_provenance: RetrievalProvenance,
replay_results: SliceScopedResults,
) -> bool:
"""Verify that a replay produces identical results."""
# Same slice?
if original_provenance.slice_id != replay_results.provenance.slice_id:
return False
# Same query embedding?
if original_provenance.query_embedding_hash != replay_results.provenance.query_embedding_hash:
return False
# Same results?
original_ids = set(original_provenance.retrieved_turn_ids)
replay_ids = set(replay_results.provenance.retrieved_turn_ids)
return original_ids == replay_ids---
8. Production Hardening
See [PRODUCTION_INVARIANTS.md](./PRODUCTION_INVARIANTS.md) for the complete specification.
8.1 The Four Non-Negotiable Invariants
| # | Invariant | Enforcement |
|---|---|---|
| 1 | Slice Boundary: `turn_id ∈ slice.turn_ids` | `SliceExport.is_turn_admissible()` |
| 2 | Provenance Completeness: All 5 fields present | `SliceInfo.has_valid_token()` |
| 3 | Non-Escalation: No token → no promotion | `is_admissible` property |
| 4 | Replay: Match on 3 hashes | Hash comparison |
8.2 New Fields for Production
SliceExport (Rust → Python):
@dataclass
class SliceInfo:
slice_id: str # Selection fingerprint
anchor_turn_id: str
turn_count: int
edge_count: int
policy_ref: PolicyRef
schema_version: str
graph_snapshot_hash: str # NEW: Content immutability proof
admissibility_token: str # NEW: Unforgeable kernel claimRetrievalProvenance (Python):
@dataclass
class RetrievalProvenance:
# ... existing fields ...
admissibility_shortfall: bool = False # NEW: Couldn't fill limit
@property
def is_admissible(self) -> bool:
"""Four conditions for admissibility."""
return (
self.retrieval_mode == "slice" and
self.slice_info is not None and
self.slice_info.has_valid_token() and
not self.admissibility_shortfall
)8.3 Float Normalization for Deterministic Hashing
Policy parameters use quantized floats to ensure cross-platform consistency:
# Quantization factor: 1e6
# Example: 0.9 → 900000
def quantize_float(value: float) -> int:
return round(value * 1_000_000)This ensures Rust and Python produce identical `params_hash` values.
8.4 Admissibility Token
The token is a content-derived hash that proves kernel authority:
// Kernel issues token (Rust)
let [sensitive field redacted]
&slice_id,
&anchor_turn_id,
&policy_id,
&policy_params_hash,
&graph_snapshot_hash,
&schema_version,
);Without a valid token, `is_admissible` returns `false`.
8.5 Graph Snapshot Hash
Detects content drift even when turn IDs stay the same:
// Computed from table statistics
GraphSnapshotHash::from_stats(
max_updated_at, // Latest update timestamp
turn_count, // Number of turns
edge_count, // Number of edges
schema_version, // Graph Kernel version
)8.6 Storage Separation
Store admissible traces separately for audit:
CREATE TABLE retrieval_traces (
id UUID PRIMARY KEY,
retrieval_mode TEXT CHECK (retrieval_mode IN ('slice', 'global')),
is_admissible BOOLEAN NOT NULL,
slice_id TEXT,
admissibility_token TEXT,
-- ...
);
CREATE INDEX idx_admissible ON retrieval_traces (is_admissible);---
9. API Reference
8.1 RAG++ Endpoints
POST /api/rag/search/slice
Slice-conditioned search with full provenance.
Request:
{
"query": "authentication flow",
"anchor_turn_id": "550e8400-e29b-41d4-a716-446655440000",
"policy_ref": {
"policy_id": "slice_policy_v1",
"params_hash": "abc123"
},
"limit": 10,
"min_similarity": 0.5
}Response:
{
"query": "authentication flow",
"results": [
{
"turn_id": "...",
"content": "...",
"role": "assistant",
"similarity": 0.92,
"trajectory": {
"depth": 5,
"sibling_order": 0,
"homogeneity": 0.8,
"temporal": 0.3,
"complexity": 2
}
}
],
"slice_info": {
"slice_id": "slice_fingerprint",
"anchor_turn_id": "...",
"turn_count": 50,
"edge_count": 49,
"policy_id": "slice_policy_v1",
"params_hash": "abc123",
"schema_version": "1.0.0"
},
"provenance": {
"query_id": "...",
"retrieval_mode": "slice",
"is_admissible": true,
"slice_id": "slice_fingerprint",
"anchor_turn_id": "...",
"elapsed_ms": 42.5,
"limit_requested": 10,
"limit_returned": 5
}
}GET /api/rag/search/global
Global search (unrestricted, non-admissible).
Query Parameters:
- `query` (required): Search query
- `limit` (optional, default=10): Maximum results
Response:
{
"query": "authentication flow",
"results": [...],
"provenance": {
"query_id": "...",
"retrieval_mode": "global",
"is_admissible": false,
"slice_id": null,
"anchor_turn_id": null,
"elapsed_ms": 35.2,
"limit_requested": 10,
"limit_returned": 10
}
}---
10. Deployment
9.1 Docker Compose
# docker-compose.yml (excerpt)
services:
graph-kernel:
build:
context: ../cc-graph-kernel
dockerfile: Dockerfile.service
ports:
- "8001:8001"
environment:
- PORT=8001
- DATABASE_URL=${DATABASE_URL}
- RUST_LOG=info
profiles:
- with-kernel
backend:
environment:
- GRAPH_KERNEL_URL=http://graph-kernel:80019.2 Environment Variables
| Variable | Service | Description |
|---|---|---|
| `DATABASE_URL` | Graph Kernel | PostgreSQL connection string |
| `PORT` | Graph Kernel | Service port (default: 8001) |
| `RUST_LOG` | Graph Kernel | Log level (default: info) |
| `GRAPH_KERNEL_URL` | RAG++ | URL to Graph Kernel service |
| `GRAPH_KERNEL_TIMEOUT` | RAG++ | Request timeout in seconds |
9.3 Cloud Run Deployment
# Build and push Graph Kernel
cd core/cc-graph-kernel
gcloud builds submit --tag gcr.io/PROJECT/graph-kernel
# Deploy
gcloud run deploy graph-kernel \
--image gcr.io/PROJECT/graph-kernel \
--port 8001 \
--set-env-vars "DATABASE_URL=..." \
--allow-unauthenticated---
11. Testing
10.1 Unit Tests
# tests/test_slice_retrieval.py
def test_slice_retrieval_determinism():
"""Same anchor + policy -> same slice_id -> same results."""
query1 = SliceScopedQuery.from_slice_export(
text="test",
slice_export=slice_export,
)
query2 = SliceScopedQuery.from_slice_export(
text="test",
slice_export=slice_export,
)
assert query1.slice_id == query2.slice_id
assert query1.admissible_turn_ids == query2.admissible_turn_ids
def test_global_vs_slice_separation():
"""Global results cannot trigger promotions."""
slice_prov = RetrievalProvenance.create_slice_provenance(...)
global_prov = RetrievalProvenance.create_global_provenance(...)
assert slice_prov.is_admissible == True
assert global_prov.is_admissible == False10.2 Golden Tests (Rust)
// cc-graph-kernel/tests/service_golden.rs
#[test]
fn test_slice_determinism() {
let store = InMemoryGraphStore::from_fixture("test_graph.json");
let policy = SlicePolicyV1::default();
let slicer = ContextSlicer::new(&store, policy);
let anchor = TurnId::from_str("anchor_001").unwrap();
// Run 100 times
let mut slice_ids = HashSet::new();
for _ in 0..100 {
let slice = slicer.slice(anchor.clone()).unwrap();
slice_ids.insert(slice.slice_id.clone());
}
// All runs produce identical slice_id
assert_eq!(slice_ids.len(), 1);
}10.3 Running Tests
# Python tests
cd core/cc-rag-plus-plus
pytest tests/test_slice_retrieval.py -v
# Rust tests
cd core/cc-graph-kernel
cargo test --features service---
12. Migration Guide
11.1 From Legacy RAG++ Search
Before (Global Search Only):
results = retriever.search("authentication flow", limit=10)After (Slice-Conditioned):
# 1. Get slice from Graph Kernel
slice_export = await slice_client.get_slice(anchor_turn_id)
# 2. Slice-scoped search
results = retriever.search_slice("authentication flow", slice_export)
# 3. Check admissibility before promotion
if results.provenance.is_admissible:
promote_to_atom(results)11.2 Gradual Migration Path
1. Phase 1: Add new endpoints alongside existing
- `/api/rag/search/slice` (new)
- `/api/rag/search/global` (new)
- `/api/rag/search` (existing, unchanged)
2. Phase 2: Update consumers to use slice endpoints
3. Phase 3: Deprecate legacy search (optional)
11.3 Backwards Compatibility
The existing `/api/rag/search` endpoint remains unchanged. New slice-conditioned endpoints are additive.
---
Appendix A: Data Structures
A.1 SlicePolicyV1 (Rust)
pub struct SlicePolicyV1 {
pub version: String, // "slice_policy_v1"
pub max_nodes: usize, // Max turns in slice (256)
pub max_radius: u32, // Max hops from anchor (10)
pub phase_weights: PhaseWeights,
pub salience_weight: f32, // [0, 1]
pub distance_decay: f32, // Priority decay per hop
pub include_siblings: bool,
pub max_siblings_per_node: usize,
}A.2 SearchResult (Python)
@dataclass
class SearchResult:
turn_id: UUID
content: str
role: str
similarity: float
conversation_id: UUID
trajectory: TrajectoryCoordinates
metadata: Dict[str, Any]---
Appendix B: Error Codes
| Code | Description |
|---|---|
| `INVALID_TURN_ID` | Anchor turn ID is not a valid UUID |
| `POLICY_NOT_FOUND` | Referenced policy is not registered |
| `SLICE_FAILED` | Graph traversal failed (e.g., anchor not in store) |
| `HTTP_ERROR` | Network error communicating with Graph Kernel |
| `SERVICE_UNAVAILABLE` | Graph Kernel service is down |
---
Appendix C: Performance Considerations
C.1 Slice Size Thresholds
| Slice Size | Retrieval Strategy | Notes |
|---|---|---|
| < 100 turns | IN clause filter | Efficient, single query |
| 100-1000 turns | Client-side filter | Over-fetch then filter |
| > 1000 turns | Consider narrower policy | May indicate policy misconfiguration |
C.2 Caching
Future optimization: Cache (slice_id, query_embedding_hash) → results.
---
This documentation is auto-generated and should be kept in sync with implementation changes.
``
Promotion Decision
Attach run IDs, datasets, metrics, and reproduction commands.
Source Anchor
Comp-Core/core/retrieval/cc-rag-plus-plus/docs/GRAPH_KERNEL_INTEGRATION.md
Detected Structure
Method · Evaluation · Code Anchors · Architecture