Graph Kernel Technical Architecture
**OpenClaw CompCore — cc-graph-kernel** **Version:** 1.0.0 · **Schema:** 1.0.0 **Date:** 2026-02-13 **Author:** Mohamed Diomande
Full Public Reader
Graph Kernel Technical Architecture
OpenClaw CompCore — cc-graph-kernel
Version: 1.0.0 · Schema: 1.0.0
Date: 2026-02-13
Author: Mohamed Diomande
---
Table of Contents
1. [System Overview](#1-system-overview)
2. [Architecture Diagrams](#2-architecture-diagrams)
3. [API Reference](#3-api-reference)
4. [Data Model](#4-data-model)
5. [Core Engine](#5-core-engine)
6. [Security Model](#6-security-model)
7. [Atlas Subsystem](#7-atlas-subsystem)
8. [Deployment Guide](#8-deployment-guide)
9. [Configuration Reference](#9-configuration-reference)
10. [Operational Runbook](#10-operational-runbook)
---
1. System Overview
1.1 What is the Graph Kernel?
The Graph Kernel is a deterministic context slicing engine for conversation DAGs. It answers one question:
> Given a target turn, which other turns are allowed to influence meaning?
It provides:
- Deterministic context slicing — same anchor + same policy + same graph state → identical `slice_id`
- HMAC-signed admissibility tokens — unforgeable proof that a context slice was authorized by the kernel
- Policy-governed expansion — phase-weighted priority queues with configurable budgets
- Knowledge graph triple store — subject–predicate–object triples with confidence and provenance
1.2 Technology Stack
| Component | Technology | Purpose |
|---|---|---|
| Language | Rust 2021 edition | Performance, safety, single binary |
| Web Framework | Axum 0.7 | Async HTTP with Tower middleware |
| Async Runtime | Tokio 1.x | Multi-threaded async I/O |
| Database Driver | sqlx 0.7 | Async PostgreSQL with compile-time query checking |
| Hashing | xxhash-rust (xxh64) | Fast, deterministic fingerprinting |
| Cryptography | hmac + sha2 | HMAC-SHA256 for admissibility tokens |
| Serialization | serde + serde_json | JSON request/response handling |
| Logging | tracing + tracing-subscriber | Structured JSON logging |
| Caching | lru + parking_lot | Token verification cache |
| UUID | uuid v1 (v4 generation) | Turn and entity identifiers |
1.3 Crate Structure
cc-graph-kernel/
├── Cargo.toml # Package manifest
├── src/
│ ├── lib.rs # Public API surface, re-exports
│ ├── bin/
│ │ └── graph_kernel_service.rs # Service binary entry point
│ ├── slicer.rs # Core context slicing algorithm
│ ├── canonical.rs # Canonical byte representation for hashing
│ ├── canonical_content.rs # Content hash normalization
│ ├── types/
│ │ ├── mod.rs # Type re-exports
│ │ ├── turn.rs # TurnId, TurnSnapshot, Role, Phase
│ │ ├── edge.rs # Edge, EdgeType
│ │ ├── slice.rs # SliceExport, SliceFingerprint, AdmissibilityToken
│ │ ├── admissible.rs # AdmissibleEvidenceBundle (verified wrapper)
│ │ ├── verification.rs # TokenVerifier, VerificationMode, cache
│ │ ├── sufficiency.rs # SufficiencyPolicy, DiversityMetrics
│ │ ├── boundary.rs # SliceBoundaryGuard, BoundedQueryBuilder
│ │ ├── provenance.rs # ReplayProvenance, EmbeddingModelRef
│ │ └── incident.rs # Incident tracking, quarantine
│ ├── policy/
│ │ ├── mod.rs # Policy module, PhaseWeights
│ │ ├── v1.rs # SlicePolicyV1 (phase-weighted expansion)
│ │ └── scoring.rs # ExpansionCandidate priority scoring
│ ├── store/
│ │ ├── mod.rs # GraphStore trait
│ │ ├── postgres.rs # PostgresGraphStore (production)
│ │ └── memory.rs # InMemoryGraphStore (testing)
│ ├── service/
│ │ ├── mod.rs # Service module
│ │ ├── routes.rs # Axum route handlers
│ │ ├── state.rs # ServiceState, PolicyRegistry
│ │ └── middleware.rs # Request logging, CORS
│ └── atlas/
│ ├── mod.rs # Atlas subsystem
│ ├── snapshot.rs # GraphSnapshot, SnapshotStore
│ ├── batch_slicer.rs # BatchSlicer, SliceRegistry
│ ├── overlap.rs # OverlapAnalyzer, OverlapGraph
│ ├── influence.rs # TurnInfluence, BridgeTurn detection
│ └── bundler.rs # AtlasBundler, AtlasManifest
├── benches/
│ └── verification.rs # Criterion benchmarks
└── tests/
├── atlas_integration.rs # Atlas integration tests
└── golden.rs # Golden file tests1.4 Feature Flags
| Feature | Dependencies Added | Purpose |
|---|---|---|
| `default` | (none) | Core library only (no I/O) |
| `postgres` | sqlx, tokio | PostgreSQL graph store |
| `service` | axum, tower, tower-http, tokio, postgres | Full HTTP service binary |
---
2. Architecture Diagrams
2.1 High-Level System Architecture
flowchart TB
subgraph Clients [Client Services]
RAG["RAG++ Service<br/>:8000"]
Orbit["Orbit Server<br/>Cloud"]
Agent["Agent Gateway<br/>Clawdbot"]
Kimi["Kimi Pipeline<br/>Cron 4h"]
end
subgraph GK [Graph Kernel Service :8001]
direction TB
subgraph API [API Layer]
Slice["POST /api/slice"]
Batch["POST /api/slice/batch"]
Verify["POST /api/verify_token"]
Policy["GET/POST /api/policies"]
KG["GET/POST /api/knowledge"]
Health["GET /health/*"]
end
subgraph Engine [Core Engine]
Slicer["ContextSlicer<br/>BFS Priority Queue"]
PolicyReg["PolicyRegistry<br/>Hash-Stable Store"]
TokenAuth["AdmissibilityToken<br/>HMAC-SHA256"]
Snapshot["GraphSnapshotHash<br/>Content Immutability"]
end
subgraph Storage [Storage Layer]
PG["PostgresGraphStore<br/>sqlx Pool 2..10"]
Mem["InMemoryGraphStore<br/>Testing Only"]
end
subgraph Obs [Observability]
Logs["JSON Structured Logs"]
Trace["X-Cloud-Trace-Context"]
Probes["Liveness/Readiness/Startup"]
end
end
subgraph DB [Database Layer]
Supabase[(PostgreSQL<br/>Supabase us-east-1)]
SQLite[(SQLite Cache<br/>[home-path])]
end
Clients --> API
API --> Engine
Engine --> Storage
PG --> Supabase
Kimi -->|"POST /api/knowledge/batch"| KG
RAG -->|"POST /api/slice"| Slice
Orbit -->|"POST /api/verify_token"| Verify2.2 Context Slice Generation Flow
sequenceDiagram
participant C as Client
participant A as API Layer
participant P as PolicyRegistry
participant S as ContextSlicer
participant G as GraphStore
participant T as TokenAuthority
participant DB as PostgreSQL
C->>+A: POST /api/slice {anchor_turn_id, policy_ref?}
A->>+P: resolve(policy_ref)
P-->>-A: SlicePolicyV1
A->>+S: slice(anchor_id)
S->>+G: get_turn(anchor_id)
G->>+DB: SELECT * FROM memory_turns
DB-->>-G: TurnSnapshot
G-->>-S: anchor_turn
rect rgb(240, 248, 255)
Note over S,DB: Priority Queue BFS Expansion
loop While frontier not empty AND |selected| < max_nodes
S->>S: pop highest-priority candidate
S->>G: get_parents(turn_id)
S->>G: get_children(turn_id)
S->>G: get_siblings(turn_id, limit)
Note over S: Add unvisited to frontier<br/>with distance + 1
end
end
S->>+G: get_edges(selected_turn_ids)
G->>DB: SELECT edges
G-->>-S: Vec<Edge>
S->>S: compute_graph_snapshot_hash()
S->>S: compute_slice_fingerprint()
S->>+T: issue_hmac(secret, slice_fields)
T-->>-S: AdmissibilityToken
S->>S: AdmissibleEvidenceBundle::from_verified()
S-->>-A: AdmissibleEvidenceBundle
A-->>-C: {slice: SliceExportDto, policy_ref}2.3 Token Verification Flow
sequenceDiagram
participant D as Downstream Service
participant A as Graph Kernel API
participant T as TokenAuthority
D->>+A: POST /api/verify_token
Note over D,A: {token, slice_id, anchor_id,<br/>policy_id, params_hash,<br/>graph_snapshot_hash, schema_version}
A->>+T: verify_hmac(secret, claimed, params)
T->>T: expected = HMAC-SHA256(secret, canonical_string)
T->>T: constant_time_compare(claimed[0..16], expected[0..16])
T-->>-A: valid: bool
alt Token Valid
A-->>D: {"valid": true}
else Token Invalid
A-->>D: {"valid": false, "reason": "Token does not match expected HMAC"}
end
deactivate A2.4 Knowledge Triple Lifecycle
flowchart LR
subgraph Sources [Data Sources]
Kimi[Kimi-K2<br/>Conversation Extraction]
Topo[Topology Ingester<br/>ARCHITECTURE.md]
Manual[Manual Ingestion<br/>API Calls]
end
subgraph GK [Graph Kernel]
Batch["POST /api/knowledge/batch"]
Single["POST /api/knowledge"]
Store["knowledge_graph table"]
Query["GET /api/knowledge"]
Stats["GET /api/knowledge/stats"]
end
subgraph Consumers [Consumers]
Benchmark[Benchmark Suite]
Proxy[SQLite Proxy :8002]
Agent[Agent Queries]
end
Sources --> Batch
Sources --> Single
Batch --> Store
Single --> Store
Store --> Query
Store --> Stats
Query --> Consumers
Stats --> Consumers---
3. API Reference
3.1 Context Slicing Endpoints
`POST /api/slice` — Generate Context Slice
Construct a deterministic context slice around an anchor turn.
Request:
{
"anchor_turn_id": "726d8410-3a61-448b-a2d9-463598bbdda3",
"policy_ref": {
"policy_id": "slice_policy_v1",
"params_hash": "a1b2c3d4e5f6..."
}
}| Field | Type | Required | Description |
|---|---|---|---|
| `anchor_turn_id` | string (UUID) | ✅ | The turn to slice around |
| `policy_ref` | object | ❌ | Policy reference. Uses default if omitted |
| `policy_ref.policy_id` | string | ❌ | Policy version identifier |
| `policy_ref.params_hash` | string | ❌ | Policy parameters hash |
Response (200):
{
"slice": {
"slice_id": "f8a23b...",
"anchor_turn_id": "726d8410-...",
"turn_ids": ["id1", "id2", "id3"],
"edge_count": 5,
"policy_id": "slice_policy_v1",
"policy_params_hash": "a1b2c3...",
"schema_version": "1.0.0",
"graph_snapshot_hash": "e7d1f9...",
"admissibility_token": "c4a8b2d1e5f60789..."
},
"policy_ref": {
"policy_id": "slice_policy_v1",
"params_hash": "a1b2c3..."
}
}Error Responses:
| Status | Code | Cause |
|---|---|---|
| 400 | `INVALID_TURN_ID` | Malformed UUID |
| 404 | `POLICY_NOT_FOUND` | Referenced policy not registered |
| 500 | `SLICE_FAILED` | Internal error during slice generation |
---
`POST /api/slice/batch` — Batch Slice Generation
Generate multiple slices in a single request.
Request:
{
"anchor_turn_ids": ["uuid1", "uuid2", "uuid3"],
"policy_ref": null
}Response (200):
{
"slices": [
{ "slice_id": "...", "anchor_turn_id": "uuid1", ... },
{ "slice_id": "...", "anchor_turn_id": "uuid2", ... }
],
"policy_ref": { "policy_id": "slice_policy_v1", "params_hash": "..." },
"success_count": 2,
"errors": [
{ "anchor_turn_id": "uuid3", "error": "Anchor turn not found" }
]
}---
`POST /api/verify_token` — Verify Admissibility Token
Verify an admissibility token without exposing the HMAC secret.
Request:
{
"admissibility_token": "c4a8b2d1e5f60789...",
"slice_id": "f8a23b...",
"anchor_turn_id": "726d8410-...",
"policy_id": "slice_policy_v1",
"policy_params_hash": "a1b2c3...",
"graph_snapshot_hash": "e7d1f9...",
"schema_version": "1.0.0"
}Response (200):
{
"valid": true,
"reason": null
}---
3.2 Policy Management Endpoints
`GET /api/policies` — List Registered Policies
Response (200):
{
"policies": [
{ "policy_id": "slice_policy_v1", "params_hash": "a1b2c3..." }
],
"registry_fingerprint": "21824822487c24ac"
}`POST /api/policies` — Register a New Policy
Request:
{
"policy": {
"version": "slice_policy_v1",
"max_nodes": 128,
"max_radius": 5,
"phase_weights": {
"synthesis": 1.0,
"planning": 0.9,
"consolidation": 0.6,
"debugging": 0.5,
"exploration": 0.3
},
"salience_weight": 0.3,
"distance_decay": 0.9,
"include_siblings": true,
"max_siblings_per_node": 5
}
}---
3.3 Knowledge Graph Endpoints
`GET /api/knowledge` — Query Knowledge Triples
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
| `subject` | string | — | Filter by exact subject match |
| `predicate` | string | — | Filter by exact predicate match |
| `object` | string | — | Filter by exact object match |
| `min_confidence` | float | — | Minimum confidence threshold |
| `limit` | integer | 50 | Max results (capped at 500) |
Example:
GET /api/knowledge?subject=clawdbot&predicate=uses&limit=100Response (200):
{
"triples": [
{
"id": 30817,
"subject": "clawdbot",
"predicate": "uses",
"object": "discord.js",
"confidence": 0.95,
"source": "topology-ingester",
"created_at": "2026-02-13 19:37:55.055920+00"
}
],
"total": 1
}`POST /api/knowledge` — Add Single Triple
Request:
{
"subject": "clawdbot",
"predicate": "deployed_on",
"object": "macbook-air",
"confidence": 0.9,
"source": "manual"
}Response (200):
{
"added": 1,
"updated": 0,
"total": 1
}On conflict (duplicate subject+predicate+object), updates confidence to `GREATEST(existing, new)` and updates source.
`POST /api/knowledge/batch` — Batch Triple Ingestion
Request: Array of `KnowledgeTriple` objects.
[
{"subject": "a", "predicate": "uses", "object": "b", "confidence": 0.9, "source": "pipeline"},
{"subject": "c", "predicate": "depends_on", "object": "d", "confidence": 0.8, "source": "pipeline"}
]Response (200):
{
"added": 1,
"updated": 1,
"total": 2
}All inserts execute within a single database transaction.
`GET /api/knowledge/stats` — Knowledge Graph Statistics
Response (200):
{
"total_triples": 3502,
"unique_subjects": 221,
"unique_predicates": 88,
"top_predicates": [
{"predicate": "has_file", "count": 810},
{"predicate": "needs_to", "count": 467}
]
}---
3.4 Health Check Endpoints
`GET /health` — Detailed Health
Returns full service status including database connectivity and pool statistics.
{
"status": "healthy",
"version": "0.1.0",
"schema_version": "1.0.0",
"policy_count": 1,
"registry_fingerprint": "21824822487c24ac",
"database": {
"connected": true,
"pool_size": 2,
"pool_idle": 1,
"pool_max": 10
}
}`GET /health/live` — Liveness Probe
Returns 200 if the process is alive. Does not check database.
{"status": "alive"}`GET /health/ready` — Readiness Probe
Returns 200 if database is connected, 503 otherwise.
{"ready": true, "database": true}`GET /health/startup` — Startup Probe
Used by Cloud Run to determine when the container is ready for traffic.
---
4. Data Model
4.1 Knowledge Graph Schema
CREATE TABLE knowledge_graph (
id BIGSERIAL PRIMARY KEY,
subject TEXT NOT NULL,
predicate TEXT NOT NULL,
object TEXT NOT NULL,
confidence DOUBLE PRECISION DEFAULT 0.5,
source TEXT DEFAULT 'unknown',
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(subject, predicate, object)
);
-- Indexes
CREATE INDEX idx_knowledge_subject ON knowledge_graph(subject);
CREATE INDEX idx_knowledge_predicate ON knowledge_graph(predicate);
CREATE INDEX idx_knowledge_confidence ON knowledge_graph(confidence DESC);4.2 Conversation DAG Schema
CREATE TABLE memory_turns (
id UUID PRIMARY KEY,
conversation_id UUID REFERENCES conversations(id),
parent_turn_id UUID REFERENCES memory_turns(id),
session_id TEXT,
role TEXT, -- 'user', 'assistant', 'system'
phase TEXT, -- 'synthesis', 'planning', 'consolidation', 'debugging', 'exploration'
content_text TEXT,
content_hash TEXT, -- SHA-256 of normalized content
salience FLOAT, -- 0.0 - 1.0
depth INTEGER,
word_count INTEGER,
commitment FLOAT, -- 0.0 - 1.0
uncertainty FLOAT, -- 0.0 - 1.0
recovery_margin FLOAT, -- 0.0 - 1.0
created_at TIMESTAMPTZ DEFAULT NOW(),
trajectory_coord JSONB -- Spatial coordinates for visualization
);
CREATE TABLE conversations (
id UUID PRIMARY KEY,
project_id UUID,
title TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE edges (
id UUID PRIMARY KEY,
parent_turn_id UUID REFERENCES memory_turns(id),
child_turn_id UUID REFERENCES memory_turns(id),
edge_type TEXT -- 'reply', 'branch', 'merge'
);4.3 Entity Relationship Diagram
erDiagram
knowledge_graph {
bigserial id PK
text subject
text predicate
text object
float confidence
text source
timestamptz created_at
}
memory_turns {
uuid id PK
uuid conversation_id FK
uuid parent_turn_id FK
text session_id
text role
text phase
text content_text
text content_hash
float salience
int depth
int word_count
float commitment
float uncertainty
float recovery_margin
timestamptz created_at
}
conversations {
uuid id PK
uuid project_id
text title
timestamptz created_at
}
edges {
uuid id PK
uuid parent_turn_id FK
uuid child_turn_id FK
text edge_type
}
memory_turns }o--|| conversations : "belongs_to"
memory_turns ||--o{ memory_turns : "parent_turn_id"
memory_turns ||--o{ edges : "parent_turn_id"
memory_turns ||--o{ edges : "child_turn_id"4.4 Triple Model
Each knowledge triple represents a factual assertion:
(subject, predicate, object) + metadata| Field | Type | Constraints | Example |
|---|---|---|---|
| `subject` | TEXT | NOT NULL | `"clawdbot"` |
| `predicate` | TEXT | NOT NULL | `"uses"` |
| `object` | TEXT | NOT NULL | `"discord.js"` |
| `confidence` | FLOAT | 0.0–1.0, default 0.5 | `0.95` |
| `source` | TEXT | default `'unknown'` | `"topology-ingester"` |
The triple `(subject, predicate, object)` has a UNIQUE constraint. On conflict, the higher confidence value is retained.
---
5. Core Engine
5.1 Context Slicer Algorithm
The `ContextSlicer` uses a priority-queue BFS expansion:
Algorithm: PolicyWeightedBFS
Input: anchor_id, policy (max_nodes, max_radius, phase_weights, ...)
Output: AdmissibleEvidenceBundle (verified slice)
1. FETCH anchor turn from store
2. CREATE frontier = MaxHeap<ExpansionCandidate>
3. ADD anchor to frontier with distance=0, priority=score(anchor, policy)
4. INIT selected = [], visited = {anchor_id}
5. WHILE frontier is not empty AND |selected| < max_nodes:
a. POP highest-priority candidate from frontier
b. IF candidate.distance > max_radius: CONTINUE
c. ADD candidate.turn to selected
d. FOR each parent, child of candidate.turn:
- IF not visited:
ADD to frontier with distance+1
MARK as visited
e. IF include_siblings AND max_siblings_per_node > 0:
FOR each sibling (same parent, up to limit):
ADD to frontier with same distance
MARK as visited
6. FETCH edges between selected turns
7. COMPUTE graph_snapshot_hash from content hashes (or stats fallback)
8. COMPUTE slice_fingerprint from (anchor, turn_ids, edges, policy)
9. ISSUE admissibility_token = HMAC-SHA256(secret, canonical_fields)
10. WRAP in AdmissibleEvidenceBundle (verified proof)
11. RETURN bundle5.2 Priority Scoring
Each expansion candidate receives a priority score:
priority = phase_weight(turn.phase) × (1 - salience_weight + salience_weight × turn.salience)
× distance_decay^distance| Component | Effect |
|---|---|
| `phase_weight` | Synthesis turns (1.0) prioritized over Exploration (0.3) |
| `salience_weight × turn.salience` | High-salience turns get priority boost |
| `distance_decay^distance` | Priority decays exponentially with graph distance |
5.3 Determinism Guarantees
1. Canonical sorting: Turns sorted by TurnId, edges sorted by (parent, child)
2. Quantized floats: Policy parameters hashed as i64 (float × 10⁶, rounded)
3. Content-derived fingerprints: `slice_id = xxHash64(anchor, turn_ids, edges, policy_id, params_hash, schema_version)`
4. Invariant: Same anchor + same policy + same graph state → identical `slice_id`
5.4 GraphStore Trait
#[async_trait]
pub trait GraphStore {
async fn get_turn(&self, id: &TurnId) -> Result<Option<TurnSnapshot>>;
async fn get_parents(&self, id: &TurnId) -> Result<Vec<TurnId>>;
async fn get_children(&self, id: &TurnId) -> Result<Vec<TurnId>>;
async fn get_siblings(&self, id: &TurnId, limit: usize) -> Result<Vec<TurnId>>;
async fn get_edges(&self, turn_ids: &[TurnId]) -> Result<Vec<Edge>>;
async fn is_healthy(&self) -> bool;
fn pool_stats(&self) -> PoolStats;
}Two implementations:
- `PostgresGraphStore`: Production store with connection pooling (sqlx)
- `InMemoryGraphStore`: Test-only store using `HashMap`
---
6. Security Model
6.1 Admissibility Token Protocol
┌───────────────────────────────────────────────────────────────┐
│ TRUST BOUNDARY │
│ │
│ Graph Kernel (TRUSTED) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ KERNEL_HMAC_SECRET (never exposed) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ [sensitive field redacted], canonical)[0..16] │ │
│ │ [sensitive field redacted]) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ (token travels with slice) │
│ Downstream (UNTRUSTED) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Receives: SliceExport + admissibility_token │ │
│ │ Verifies: POST /api/verify_token │ │
│ │ Result: valid/invalid (no secret exposed) │ │
│ └─────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘6.2 Canonical String Construction
The HMAC input is constructed as a pipe-separated canonical string:
"{slice_id}|{anchor_turn_id}|{policy_id}|{policy_params_hash}|{graph_snapshot_hash}|{schema_version}|admissibility_token_v2_hmac"This binds all provenance fields together. Changing any field invalidates the token.
6.3 Verification Properties
- Constant-time comparison prevents timing attacks
- Token truncation to 128 bits (16 bytes) balances security and size
- No secret exposure — verification endpoint computes expected token server-side
- Type-level enforcement — `AdmissibleEvidenceBundle` can only be constructed through `from_verified()`, making unverified slices unrepresentable in the type system
6.4 Invariants
| Invariant | Description | Enforcement |
|---|---|---|
| INV-GK-001 | Same input → same slice_id | Canonical sorting, quantized hashing |
| INV-GK-002 | Provenance completeness | SliceExport requires all 6 provenance fields |
| INV-GK-003 | No Phantom Authority | AdmissibleEvidenceBundle type (can only be created via verification) |
| INV-GK-004 | Non-Escalation | Missing [sensitive field redacted] |
---
7. Atlas Subsystem
The Atlas subsystem provides higher-level graph analysis capabilities built on top of the core slicer.
7.1 Components
| Component | Purpose |
|---|---|
| `GraphSnapshot` | Capture a point-in-time view of graph state |
| `BatchSlicer` | Generate slices for multiple anchors efficiently |
| `SliceRegistry` | Index and look up slices by various keys |
| `OverlapAnalyzer` | Detect and measure overlap between slices |
| `TurnInfluence` | Compute influence scores for turns across slices |
| `AtlasBundler` | Package all analysis into a manifest |
7.2 Influence Analysis
pub struct TurnInfluence {
pub turn_id: TurnId,
pub scores: InfluenceScores,
pub phase_counts: PhaseCounts,
}
pub struct InfluenceScores {
pub frequency: f64, // How often this turn appears across slices
pub centrality: f64, // How central this turn is in the graph
pub bridge_score: f64, // Whether this turn bridges otherwise separate components
}7.3 Overlap Detection
The `OverlapAnalyzer` computes pairwise overlap between slices using Jaccard similarity:
overlap(A, B) = |A.turn_ids ∩ B.turn_ids| / |A.turn_ids ∪ B.turn_ids|This enables detection of redundant slices and identification of turn clusters.
---
8. Deployment Guide
8.1 Local Development
# Clone and build
cd Desktop/Comp-Core/core/semantic/cc-graph-kernel
cargo build --release --features service
# Set environment
export DATABASE_URL="postgres://user:pass@localhost:5432/compcore"
export KERNEL_HMAC_SECRET="your-secret-key-at-least-32-bytes"
export PORT=8001
export HOST=[ip]
export LOG_FORMAT=pretty
export RUST_LOG=graph_kernel_service=debug
# Run
cargo run --release --features service --bin graph_kernel_service8.2 Production (launchd on macOS)
The service runs as a launchd daemon:
Plist: `Desktop/Comp-Core/services/launchd/com.compcore.graph-kernel.plist`
Start script: `Desktop/Comp-Core/scripts/start-graph-kernel.sh`
#!/bin/bash
export DATABASE_URL="postgres://..."
export KERNEL_HMAC_SECRET="..."
export PORT=8001
export HOST=[ip]
cd [home]/Desktop/Comp-Core/core/semantic/cc-graph-kernel
exec ./target/release/graph_kernel_serviceManagement:
# Start
launchctl load Desktop/Comp-Core/services/launchd/com.compcore.graph-kernel.plist
# Stop
launchctl unload Desktop/Comp-Core/services/launchd/com.compcore.graph-kernel.plist
# Status
curl -s http://[ip]:8001/health | jq8.3 Docker
FROM rust:1.77 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release --features service --bin graph_kernel_service
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/graph_kernel_service /usr/local/bin/
EXPOSE 8001
CMD ["graph_kernel_service"]8.4 Google Cloud Run
# cloudbuild-service.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/graph-kernel:$COMMIT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/graph-kernel:$COMMIT_SHA']
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args:
- run
- deploy
- graph-kernel
- --image=gcr.io/$PROJECT_ID/graph-kernel:$COMMIT_SHA
- --port=8001
- --memory=1Gi
- --cpu=1
- --max-instances=10
- --set-secrets=DATABASE_URL=database-url:latest,KERNEL_HMAC_SECRET=kernel-hmac-[sensitive field redacted]---
9. Configuration Reference
9.1 Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
| `DATABASE_URL` | ✅ | — | PostgreSQL connection string |
| `KERNEL_HMAC_SECRET` | ✅ (prod) | `development_only_secret...` | HMAC secret for token signing |
| `PORT` | ❌ | `8001` | Service listen port |
| `HOST` | ❌ | `[ip]` | Service bind address |
| `RUST_LOG` | ❌ | `info` | Log level (trace/debug/info/warn/error) |
| `LOG_FORMAT` | ❌ | `json` | `json` for production, `pretty` for development |
9.2 Connection Pool Settings
Configured in `PostgresGraphStore::from_env()`:
| Setting | Value | Purpose |
|---|---|---|
| `min_connections` | 2 | Minimum idle connections |
| `max_connections` | 10 | Maximum pool size |
| `test_before_acquire` | true | Validate connections before use |
| `idle_timeout` | 300s | Close idle connections after 5 minutes |
| `max_lifetime` | 1800s | Maximum connection age (30 minutes) |
| `acquire_timeout` | 30s | Timeout waiting for a connection |
9.3 Default Policy Parameters
| Parameter | Default | Range | Description |
|---|---|---|---|
| `max_nodes` | 256 | 1–∞ | Maximum turns per slice |
| `max_radius` | 10 | 0–∞ | Maximum graph hops from anchor |
| `synthesis_weight` | 1.0 | 0.0–1.0 | Synthesis phase importance |
| `planning_weight` | 0.9 | 0.0–1.0 | Planning phase importance |
| `consolidation_weight` | 0.6 | 0.0–1.0 | Consolidation phase importance |
| `debugging_weight` | 0.5 | 0.0–1.0 | Debugging phase importance |
| `exploration_weight` | 0.3 | 0.0–1.0 | Exploration phase importance |
| `salience_weight` | 0.3 | 0.0–1.0 | Salience contribution to priority |
| `distance_decay` | 0.9 | 0.0–1.0 | Priority decay per hop |
| `include_siblings` | true | bool | Expand to sibling turns |
| `max_siblings_per_node` | 5 | 0–∞ | Sibling expansion limit |
---
10. Operational Runbook
10.1 Health Check
# Quick health
curl -s http://[ip]:8001/health | jq
# Liveness (process alive?)
curl -s http://[ip]:8001/health/live
# Readiness (database connected?)
curl -s http://[ip]:8001/health/ready
# Stats
curl -s http://[ip]:8001/api/knowledge/stats | jq10.2 Common Operations
# Query triples for an entity
curl -s 'http://[ip]:8001/api/knowledge?subject=clawdbot&limit=100' | jq
# Add a triple
curl -s -X POST http://[ip]:8001/api/knowledge \
-H 'Content-Type: application/json' \
-d '{"subject":"test","predicate":"is_a","object":"example","confidence":0.9,"source":"manual"}'
# Batch add
curl -s -X POST http://[ip]:8001/api/knowledge/batch \
-H 'Content-Type: application/json' \
-d '[{"subject":"a","predicate":"uses","object":"b","confidence":0.9,"source":"test"}]'
# Generate a context slice
curl -s -X POST http://[ip]:8001/api/slice \
-H 'Content-Type: application/json' \
-d '{"anchor_turn_id":"726d8410-3a61-448b-a2d9-463598bbdda3"}'
# List policies
curl -s http://[ip]:8001/api/policies | jq10.3 Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| `{"status": "degraded"}` | Database connection lost | Check Supabase status, verify DATABASE_URL |
| 503 on `/health/ready` | Pool exhausted or DB down | Restart service, check connection limits |
| High latency (>500ms) | Network to Supabase | Use SQLite proxy (:8002) for reads |
| `INVALID_TURN_ID` error | Malformed UUID in request | Verify UUID format (8-4-4-4-12 hex) |
| Token verification fails | HMAC secret mismatch | Ensure same secret in issuer and verifier |
| `SLICE_FAILED` | Anchor turn not in database | Verify turn exists in memory_turns table |
10.4 Log Analysis
# Service logs (JSON format)
tail -f Desktop/Comp-Core/logs/services/graph-kernel.log | jq
# Error logs
tail -f Desktop/Comp-Core/logs/services/graph-kernel.err.log
# Filter by request path
cat graph-kernel.log | jq 'select(.path == "/api/knowledge")'
# Filter slow requests (>500ms)
cat graph-kernel.log | jq 'select(.latency_ms > 500)'10.5 PID Management
# Check if running
cat Desktop/Comp-Core/logs/services/pids/graph-kernel.pid
ps aux | grep graph_kernel_service
# Force kill
kill $(cat Desktop/Comp-Core/logs/services/pids/graph-kernel.pid)
# Restart
Desktop/Comp-Core/scripts/start-graph-kernel.sh &---
Appendix: Related Documents
| Document | Path | Content |
|---|---|---|
| Benchmark Evaluation | `benchmarks/graph-kernel-evaluation.md` | 27-query benchmark results |
| Improvement Plan | `benchmarks/IMPROVEMENT-PLAN.md` | Entity normalization, SQLite, topology ingestion |
| System Architecture | `[home-path]` | Full OpenClaw system topology |
| Evaluation Report | `docs/GRAPH-KERNEL-EVALUATION-REPORT.md` | Comparative analysis vs industry alternatives |
| Research Paper | `docs/GRAPH-KERNEL-RESEARCH-PAPER.md` | IEEE/ACM-style research paper |
| Architecture Diagrams | `docs/architecture/diagrams/graph-kernel-architecture.md` | Original Mermaid diagrams |
---
Architecture document generated 2026-02-13 for cc-graph-kernel v0.1.0, schema v1.0.0.
Promotion Decision
Promote into a technical note or architecture paper with implementation anchors.
Source Anchor
Comp-Core/docs/GRAPH-KERNEL-ARCHITECTURE.md
Detected Structure
Method · Evaluation · References · Figures · Code Anchors · Architecture